diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index dde2dba1845..00000000000 --- a/.eslintignore +++ /dev/null @@ -1,9 +0,0 @@ -# TODO: Use eslint on js lib and generated code - -# Ignore lib/js for now, which uses jshint currently -lib/js/* -# Ignore all generated code for now -**/gen-* - -# Don't lint nested node_modules -**/node_modules diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 0aae820ecdb..00000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "env": { - "es6": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:prettier/recommended" - ], - "parserOptions": { - "ecmaVersion": 2017 - }, - "rules": { - "no-console": "off", - "no-var": "error", - "prefer-const": "error", - "no-constant-condition": [ - "error", - { - "checkLoops": false - } - ] - } -} diff --git a/.github/actions/cloudtruth/configure-action b/.github/actions/cloudtruth/configure-action new file mode 160000 index 00000000000..9ec7a0ab1c6 --- /dev/null +++ b/.github/actions/cloudtruth/configure-action @@ -0,0 +1 @@ +Subproject commit 9ec7a0ab1c6e1bf92620c4a1b3fd38c614dc1659 diff --git a/.github/actions/pypa/gh-action-pypi-publish b/.github/actions/pypa/gh-action-pypi-publish new file mode 160000 index 00000000000..717ba43cfbb --- /dev/null +++ b/.github/actions/pypa/gh-action-pypi-publish @@ -0,0 +1 @@ +Subproject commit 717ba43cfbb0387f6ce311b169a825772f54d295 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aeb1614134a..79e6e6034ba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,11 +41,13 @@ jobs: compiler: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04] + os: + - ubuntu-22.04 + - ubuntu-24.04 fail-fast: false runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | @@ -67,28 +69,81 @@ jobs: - name: Run thrift version run: /usr/local/bin/thrift -version - # only upload while building ubuntu-20.04 + # only upload while building ubuntu-24.04 - name: Archive built thrift compiler - if: matrix.os == 'ubuntu-20.04' - uses: actions/upload-artifact@v3 + if: matrix.os == 'ubuntu-24.04' + uses: actions/upload-artifact@v5 with: name: thrift-compiler path: compiler/cpp/thrift retention-days: 3 + lib-php: + needs: compiler + runs-on: ubuntu-24.04 + strategy: + matrix: + php-version: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3] + fail-fast: false + steps: + - uses: actions/checkout@v6 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, intl, xml, curl + ini-values: "error_reporting=E_ALL" + + - name: Install Dependencies + run: composer install + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-php/with-php/' | sed 's/without-php_extension/with-php_extension/' ) + + - uses: actions/download-artifact@v6 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Build Thrift Classes + run: | + mkdir -p ./lib/php/test/Resources/packages/php + mkdir -p ./lib/php/test/Resources/packages/phpv + mkdir -p ./lib/php/test/Resources/packages/phpvo + mkdir -p ./lib/php/test/Resources/packages/phpjs + mkdir -p ./lib/php/test/Resources/packages/phpcm + compiler/cpp/thrift --gen php:nsglobal="Basic" -r --out ./lib/php/test/Resources/packages/php lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:validate,nsglobal="Validate" -r --out ./lib/php/test/Resources/packages/phpv lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:validate,oop,nsglobal="ValidateOop" -r --out ./lib/php/test/Resources/packages/phpvo lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:json,nsglobal="Json" -r --out ./lib/php/test/Resources/packages/phpjs lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:classmap,server,rest,nsglobal="Classmap" -r --out ./lib/php/test/Resources/packages/phpcm lib/php/test/Resources/ThriftTest.thrift + + - name: Run Tests + run: vendor/bin/phpunit -c lib/php/phpunit.xml + lib-go: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: go: - - '1.21' - - '1.22' + - '1.24' + - '1.25' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version: ${{ matrix.go }} @@ -104,7 +159,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-go/with-go/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v6 with: name: thrift-compiler path: compiler/cpp @@ -127,8 +182,8 @@ jobs: run: make -C test/go precross - name: Upload go precross artifacts - if: matrix.go == '1.22' - uses: actions/upload-artifact@v3 + if: matrix.go == '1.25' + uses: actions/upload-artifact@v5 with: name: go-precross if-no-files-found: error @@ -138,13 +193,13 @@ jobs: lib-java-kotlin: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: GRADLE_VERSION: "8.4" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: temurin java-version: 17 @@ -182,7 +237,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-java/with-java/' | sed 's/without-kotlin/with-kotlin/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v6 with: name: thrift-compiler path: compiler/cpp @@ -200,7 +255,7 @@ jobs: run: make -C lib/java install - name: Upload java libthrift artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: libthrift if-no-files-found: error @@ -213,7 +268,7 @@ jobs: run: make -C lib/java precross - name: Upload java precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: java-precross if-no-files-found: error @@ -235,7 +290,7 @@ jobs: run: make -C lib/kotlin precross - name: Upload kotlin precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: kotlin-precross if-no-files-found: error @@ -244,11 +299,100 @@ jobs: lib/kotlin/cross-test-server/build/install/TestServer/ retention-days: 3 + lib-netstd: + needs: compiler + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + defaults: + run: + shell: bash # required by net install script + steps: + - uses: actions/checkout@v6 + + - name: Install dependencies + run: | + sudo apt-get update -yq + sudo apt-get install -y --no-install-recommends $BUILD_DEPS + sudo apt-get install -y --no-install-recommends curl openssl ca-certificates + +# This whole setup is getting worse: https://github.com/dotnet/core/discussions/9258 + - name: Set up .NET SDK (via install script) + run: | + # remove any existing install + sudo apt remove dotnet* + # install key + sudo apt install gpg + wget https://dot.net/v1/dotnet-install.asc + gpg --import dotnet-install.asc + # download and verify + wget https://dot.net/v1/dotnet-install.sh + wget https://dot.net/v1/dotnet-install.sig + gpg --verify dotnet-install.sig dotnet-install.sh + # run install script + chmod +x dotnet-install.sh + ./dotnet-install.sh --channel 10.0 + # export env vars + export DOTNET_ROOT=$HOME/.dotnet + export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools + dotnet --list-sdks + +# the sdk is installed by default, but keep this step for reference +# especially newer versions are NOT always pre-installed, so manually again +# - name: Set up .NET SDK +# run: | +# sudo add-apt-repository -y ppa:dotnet/backports +# sudo apt-get install -y --no-install-recommends dotnet-sdk-10.0 +# end + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure for netstd + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-netstd/with-netstd/') + + - uses: actions/download-artifact@v6 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Run make for netstd + run: make -C lib/netstd + + - name: Run make install for netstd + run: sudo make -C lib/netstd install + + - name: Run make check for netstd + run: make -C lib/netstd check + + - name: Run make check for test/netstd + run: make -C test/netstd check + + - name: Run make precross for test/netstd + run: make -C test/netstd precross + + - name: Upload netstd precross artifacts + uses: actions/upload-artifact@v5 + with: + name: netstd-precross + if-no-files-found: error + path: | + test/netstd/Client/bin/Release/ + test/netstd/Server/bin/Release/ + retention-days: 3 + lib-swift: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 + if: false # swift is currently broken and no maintainers around -> see THRIFT-5864 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run bootstrap run: ./bootstrap.sh @@ -257,7 +401,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-swift/with-swift/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v6 with: name: thrift-compiler path: compiler/cpp @@ -271,7 +415,7 @@ jobs: run: make -C test/swift precross - name: Upload swift precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: swift-precross if-no-files-found: error @@ -282,11 +426,11 @@ jobs: lib-rust: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: - TOOLCHAIN_VERSION: 1.65.0 + TOOLCHAIN_VERSION: 1.83.0 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | @@ -310,7 +454,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-rs/with-rs/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v6 with: name: thrift-compiler path: compiler/cpp @@ -333,7 +477,7 @@ jobs: run: make -C test/rs precross - name: Upload rust precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: rs-precross if-no-files-found: error @@ -347,14 +491,14 @@ jobs: lib-python: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: python-version: - - "3.x" + - "3.13" # Pin to 3.13 for now -> see THRIFT-5900 fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | @@ -363,7 +507,7 @@ jobs: sudo apt-get install -y --no-install-recommends curl openssl ca-certificates - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} @@ -376,12 +520,11 @@ jobs: - name: Run bootstrap run: ./bootstrap.sh - - name: Run configure 3.x - if: matrix.python-version == '3.x' + - name: Run configure run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v6 with: name: thrift-compiler path: compiler/cpp @@ -400,31 +543,134 @@ jobs: # - name: Run make install-exec-hook for python # run: sudo make -C lib/py install-exec-hook - - name: Run make check for python + - name: Run make for python libs + run: make -C lib/py + + - name: Run make check for python libs run: make -C lib/py check + - name: Run make check for python code + run: make -C test/py check + + lib-nodejs: + needs: compiler + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-node([tj])s/with-node\1s/g') + + - uses: actions/download-artifact@v6 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Run js tests + run: make -C lib/nodejs check + + - name: Run ts tests + run: make -C lib/nodets check + + lib-cpp: + needs: compiler + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + + - name: Install dependencies + run: | + sudo apt-get update -yq + sudo apt-get install -y --no-install-recommends g++ $BUILD_DEPS locales + sudo locale-gen en_US.UTF-8 + sudo locale-gen de_DE.UTF-8 + sudo update-locale + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-cpp/with-cpp/g') + + - uses: actions/download-artifact@v6 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Run make for cpp + run: make -j$(nproc) -C lib/cpp + + - name: Run make check for lib/cpp + run: make -j$(nproc) -C lib/cpp check + + - name: Run make check for test/cpp + run: make -j$(nproc) -C test/cpp check + + - name: Run make precross for cpp test + run: make -j$(nproc) -C test/cpp precross + + - name: Upload cpp precross artifacts + uses: actions/upload-artifact@v5 + with: + name: cpp-precross + if-no-files-found: error + include-hidden-files: true + path: | + test/cpp/TestClient + test/cpp/TestServer + test/cpp/.libs/TestClient + test/cpp/.libs/TestServer + lib/cpp/.libs/*.so + retention-days: 3 + + - name: Upload log files from failed test runs + uses: actions/upload-artifact@v5 + if: failure() + with: + name: lib-cpp-test-log + path: lib/cpp/test/*.xml + retention-days: 3 + cross-test: needs: - lib-java-kotlin - - lib-swift + #- lib-swift # swift is currently broken and no maintainers around -> see THRIFT-5864 - lib-rust - lib-go - lib-python - runs-on: ubuntu-20.04 + - lib-cpp + runs-on: ubuntu-24.04 strategy: matrix: - server_lang: ['java', 'kotlin', 'go', 'rs', 'swift'] + # swift is currently broken and no maintainers around -> see THRIFT-5864 + # kotlin cross test are failing -> see THRIFT-5879 + server_lang: ['java', 'go', 'rs', 'cpp'] # we always use comma join as many client langs as possible, to reduce the number of jobs - client_lang: ['java,kotlin', 'go,rs', 'swift'] + client_lang: ['java', 'go,rs,cpp'] fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.x" - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: temurin # here we intentionally use an older version so that we also verify Java 17 compiles to it @@ -434,47 +680,63 @@ jobs: - name: Install openssl and certificates (for SSL tests) run: | sudo apt-get update -yq - sudo apt-get install -y --no-install-recommends openssl ca-certificates + sudo apt-get install -y --no-install-recommends \ + openssl \ + ca-certificates \ + libboost-all-dev \ + libevent-dev - name: Download java precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v6 with: name: java-precross path: lib/java/build - name: Download kotlin precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v6 with: name: kotlin-precross path: lib/kotlin - - name: Download swift precross artifacts - uses: actions/download-artifact@v3 - with: - name: swift-precross - path: test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug + # swift is currently broken and no maintainers around -> see THRIFT-5864 + #- name: Download swift precross artifacts + # uses: actions/download-artifact@v6 + # with: + # name: swift-precross + # path: test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug - name: Download rust precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v6 with: name: rs-precross path: test/rs/bin - name: Download go precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v6 with: name: go-precross path: test/go/bin + - name: Download cpp precross artifacts + uses: actions/download-artifact@v6 + with: + name: cpp-precross + path: . + - name: Set back executable flags run: | - chmod a+x \ - lib/java/build/run* \ - lib/kotlin/cross-test-client/build/install/TestClient/bin/* \ - lib/kotlin/cross-test-server/build/install/TestServer/bin/* \ - test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/* \ - test/rs/bin/* \ - test/go/bin/* + chmod a+x lib/java/build/run* + chmod a+x lib/kotlin/cross-test-client/build/install/TestClient/bin/* + chmod a+x lib/kotlin/cross-test-server/build/install/TestServer/bin/* + # THRIFT-5864 chmod a+x test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/* + chmod a+x test/rs/bin/* + chmod a+x test/go/bin/* + chmod a+x test/cpp/* + chmod a+x test/cpp/.libs/* + chmod a+x lib/cpp/.libs/*.so + + - name: Create tmp domain socket folder + run: mkdir /tmp/v0.16 - name: Run cross test env: @@ -487,10 +749,10 @@ jobs: --client ${{ matrix.client_lang }} - name: Upload log files from failed cross test runs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 if: failure() with: - name: cross-test-log + name: cross-test-log_${{ matrix.server_lang }}-${{ matrix.client_lang }} path: test/log/ retention-days: 3 diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 71748e8fc4d..508d2f0e666 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -14,9 +14,9 @@ permissions: jobs: compiler: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml new file mode 100644 index 00000000000..deb08c3e3f3 --- /dev/null +++ b/.github/workflows/msvc.yml @@ -0,0 +1,129 @@ +name: MSVC Build + +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] + +permissions: + contents: read + packages: write + +jobs: + build: + runs-on: windows-2022 + env: + THRIFT_BUILD_DIR: C:\thrift-build + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Ensure expected workspace path + shell: pwsh + run: | + if (-not (Test-Path 'C:\src')) { New-Item -Path 'C:\src' -ItemType Directory | Out-Null } + if (Test-Path 'C:\src\thrift') { Remove-Item 'C:\src\thrift' -Recurse -Force } + cmd /c mklink /J C:\src\thrift $env:GITHUB_WORKSPACE + + - name: Configure build output directory + shell: pwsh + run: | + New-Item -Path $env:THRIFT_BUILD_DIR -ItemType Directory -Force | Out-Null + + - name: Set Docker image name + shell: pwsh + env: + OWNER: ${{ github.repository_owner }} + run: | + $image = "ghcr.io/{0}/thrift-build" -f $env:OWNER.ToLower() + "DOCKER_IMAGE=$image" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Compute Docker image tag + shell: pwsh + run: | + $hash = (Get-FileHash -Algorithm SHA256 'build/docker/msvc2017/Dockerfile').Hash.ToLower().Substring(0, 12) + "IMAGE_TAG=msvc2017-$hash" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Pull cached image + id: pull_cached + continue-on-error: true + shell: pwsh + run: | + $needBuild = $true + + Write-Host "Attempting to pull hash-based tag: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" + docker pull "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" 2>&1 | Out-Host + if ($LASTEXITCODE -eq 0) { + Write-Host "Successfully pulled cached image with hash tag" + $needBuild = $false + } else { + Write-Host "Hash tag not found, no fallback configured. Will build from scratch." + $needBuild = $true + } + + Write-Host "Setting outputs: need_build=$needBuild" + "need_build=$needBuild" >> $env:GITHUB_OUTPUT + + - name: Build Docker image + if: steps.pull_cached.outputs.need_build == 'true' + shell: pwsh + run: | + Write-Host "Building with tag: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" + docker build -t "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" -f build\docker\msvc2017\Dockerfile 'build\' + if ($LASTEXITCODE -ne 0) { + Write-Error "Docker build failed" + exit 1 + } + Write-Host "Verifying tags were created:" + docker images "$($env:DOCKER_IMAGE)" + + - name: Push Docker image + if: github.event_name != 'pull_request' && steps.pull_cached.outputs.need_build == 'true' + shell: pwsh + run: | + Write-Host "Pushing hash-based tag only: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" + docker push "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to push hash-based tag" + exit 1 + } + Write-Host "Successfully pushed hash-tagged image" + + - name: Build and test inside container + shell: pwsh + run: | + docker run -v c:\src\thrift:C:\Thrift -v "${env:THRIFT_BUILD_DIR}:C:\build" --rm -t "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" c:\thrift\build\docker\msvc2017\build.bat + + - name: Check test results + if: always() + shell: pwsh + run: | + $logPath = Join-Path $env:THRIFT_BUILD_DIR 'Testing\Temporary\LastTest.log' + if (Test-Path $logPath) { + $content = Get-Content $logPath -Raw + if ($content -match 'Test Failed\.') { + Write-Error "Tests failed - check LastTest.log artifact for details" + exit 1 + } else { + Write-Host "All tests passed" + } + } else { + Write-Warning "LastTest.log not found at $logPath" + } + + - name: Upload LastTest log + if: always() + uses: actions/upload-artifact@v4 + with: + name: msvc2017-LastTest-log + path: ${{ env.THRIFT_BUILD_DIR }}\Testing\Temporary\LastTest.log + if-no-files-found: warn diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..ab1b91e0fa8 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,52 @@ +# +# Apache Thrift release publishing workflow +# +# When a release is created in GitHub, it should be created in pre-release +# mode first. This will trigger a "prereleased" event which will cause this +# workflow to run and publish packages to various package managers. You +# must check the Actions tab in GitHub to see the result of the workflow. +# +# github.event.action is either "prereleased" or "released" and corresponds +# with a named environment in CloudTruth +# +# | Destinations +# Language | Prereleased | Released +# ----------+---------------+--------------- +# py | test.pypi.org | pypi.org +# +--- +name: Publish + +on: + release: + types: + - prereleased + - released + +permissions: + contents: read + +jobs: + pypi: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + submodules: recursive + - uses: actions/setup-python@v6 + - name: Get configuration and secrets from CloudTruth + uses: ./.github/actions/cloudtruth/configure-action + with: + apikey: "${{ secrets.CLOUDTRUTH_API_KEY }}" + project: "${{ github.repository }}" + environment: "${{ github.event.action }}" + - name: build sdist + run: "cd lib/py && python setup.py sdist" + - name: Publish to PyPI + uses: ./.github/actions/pypa/gh-action-pypi-publish + with: + password: "${{ env.PYPI_PASSWORD }}" + repository_url: "${{ env.PYPI_REPOSITORY }}" + packages_dir: lib/py/dist diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 4fc292dc79c..12859dbb60b 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -33,10 +33,10 @@ jobs: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.8" diff --git a/.github/workflows/release_rust.yml b/.github/workflows/release_rust.yml new file mode 100644 index 00000000000..933cddb656e --- /dev/null +++ b/.github/workflows/release_rust.yml @@ -0,0 +1,48 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +name: Release Rust Packages + +on: + push: + tags: + - "*" + pull_request: + branches: + - master + paths: + - ".github/workflows/release_rust.yml" + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Dryrun + working-directory: lib/rs + run: cargo publish --dry-run + + - name: Publish + working-directory: lib/rs + # Only publish if it's a tag and the tag is not a pre-release + if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }} + run: cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.gitignore b/.gitignore index cb8029c9888..9fc033fd149 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ project.lock.json /compiler/cpp/src/thrift/plugin/gen.stamp /compiler/cpp/Debug /compiler/cpp/Release +/compiler/cpp/compiler/Debug +/compiler/cpp/compiler/Release /compiler/cpp/src/thrift/libparse.a /compiler/cpp/src/thrift/thriftl.cc /compiler/cpp/src/thrift/thrifty.cc @@ -209,7 +211,6 @@ project.lock.json /lib/delphi/**/*.local /lib/delphi/**/*.dcu /lib/delphi/**/*.2007 -/lib/delphi/**/codegen/*.bat /lib/erl/.eunit /lib/erl/.generated /lib/erl/.rebar/ @@ -253,14 +254,13 @@ project.lock.json /lib/perl/pm_to_blib /lib/py/build /lib/py/thrift.egg-info/ -/lib/rb/Gemfile.lock /lib/rb/debug_proto_test /lib/rb/.config /lib/rb/ext/conftest.dSYM/ /lib/rb/ext/mkmf.log /lib/rb/ext/thrift_native.bundle /lib/rb/ext/thrift_native.so -/lib/rb/test/ +#/lib/rb/test/ /lib/rb/thrift-*.gem /lib/php/src/ext/thrift_protocol/Makefile.* /lib/php/src/ext/thrift_protocol/build/ @@ -279,9 +279,8 @@ project.lock.json /lib/php/src/ext/thrift_protocol/run-tests.php /lib/php/src/ext/thrift_protocol/thrift_protocol.la /lib/php/src/ext/thrift_protocol/tmp-php.ini -/lib/php/src/packages/ -/lib/php/test/TEST-*.xml -/lib/php/test/packages/ +/lib/php/tests/Resources/packages/ +/lib/php/test/test-log-junit.xml /lib/py/dist/ /lib/erl/logs/ /lib/go/pkg @@ -373,7 +372,6 @@ project.lock.json /test/hs/TestServer /test/php/php_ext_dir/ /test/py.twisted/_trial_temp/ -/test/rb/Gemfile.lock /test/netstd/**/bin /test/netstd/**/obj /test/netstd/**/launchSettings.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..bbaf357b397 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule ".github/actions/cloudtruth/configure-action"] + path = .github/actions/cloudtruth/configure-action + url = https://github.com/cloudtruth/configure-action +[submodule ".github/actions/pypa/gh-action-pypi-publish"] + path = .github/actions/pypa/gh-action-pypi-publish + url = https://github.com/pypa/gh-action-pypi-publish diff --git a/.travis.yml b/.travis.yml index b771d70a4a5..130b4be3842 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ env: - SCRIPT="cmake.sh" - BUILD_ARG="" - BUILD_ENV="-e CC=gcc -e CXX=g++ -e THRIFT_CROSSTEST_CONCURRENCY=4" - - DISTRO=ubuntu-bionic + - DISTRO=ubuntu-focal - BUILD_LIBS="CPP C_GLIB JAVA PYTHON TESTING TUTORIALS" # only meaningful for CMake builds - TRAVIS_BUILD_STAGE=test # DOCKER_REPO (this works for all builds as a source for docker images - you can override for fork builds in your Travis settings) @@ -58,12 +58,6 @@ env: jobs: include: # ========================= stage: docker ========================= - - stage: docker - script: true - env: - - JOB="Docker Build ubuntu-bionic 18.04 LTS" - - DISTRO=ubuntu-bionic - - TRAVIS_BUILD_STAGE=docker - script: true env: - JOB="Docker Build ubuntu-focal 20.04 LTS" @@ -74,6 +68,11 @@ jobs: - JOB="Docker Build ubuntu-jammy 22.04 LTS" - DISTRO=ubuntu-jammy - TRAVIS_BUILD_STAGE=docker + - script: true + env: + - JOB="Docker Build ubuntu-noble 24.04 LTS" + - DISTRO=ubuntu-noble + - TRAVIS_BUILD_STAGE=docker # ========================= stage: thrift ======================= # ------------------------- phase: cross ------------------------ @@ -131,12 +130,6 @@ jobs: - DISTRO=ubuntu-focal - SCRIPT="autotools.sh" - - script: build/docker/run.sh - env: - - JOB="Autotools (Ubuntu Bionic)" - - DISTRO=ubuntu-bionic - - SCRIPT="autotools.sh" - # ------------------------- phase: cmake ------------------------ - script: build/docker/run.sh env: diff --git a/ApacheThrift.nuspec b/ApacheThrift.nuspec index cd9a29c6c90..d0c6501aecf 100644 --- a/ApacheThrift.nuspec +++ b/ApacheThrift.nuspec @@ -19,14 +19,14 @@ the "Thrift" project. 2. nuget setApiKey 3. nuget pack ApacheThrift.nuspec -Symbols -SymbolPackageFormat snupkg - 4. nuget push ApacheThrift.0.20.0.nupkg -Source https://api.nuget.org/v3/index.json + 4. nuget push ApacheThrift.0.23.0.nupkg -Source https://api.nuget.org/v3/index.json --> ApacheThrift - 0.20.0 - Apache Thrift 0.20.0 + 0.23.0 + Apache Thrift 0.23.0 Apache Thrift Developers Apache Software Foundation Apache-2.0 @@ -36,7 +36,7 @@ Contains runtime libraries from lib/netstd for netstandard2.0 framework development. - + Apache Thrift RPC diff --git a/CHANGES.md b/CHANGES.md index bc2fed4750e..cc89059131b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,170 @@ - # Apache Thrift Changelog +## 0.22.0 + +### Build Process + +- [THRIFT-5836](https://issues.apache.org/jira/browse/THRIFT-5836) - 0.21.0 fails to build from sources at Arch Linux: No rule to make target 'Thrift5272.thrift', needed by 'gen-cpp/Thrift5272_types.h' +- [THRIFT-5860](https://issues.apache.org/jira/browse/THRIFT-5860) - cmake 3.5 as a minimum version does not work with cmake 4.0.0 + +### C glib + +- [THRIFT-5817](https://issues.apache.org/jira/browse/THRIFT-5817) - Avoid copy of TUuid + +### C++ + +- [THRIFT-5637](https://issues.apache.org/jira/browse/THRIFT-5637) - Thrift compiler should be able to output c++ Aggregate types +- [THRIFT-5667](https://issues.apache.org/jira/browse/THRIFT-5667) - Make ThriftConfig.cmake relocatable +- [THRIFT-5817](https://issues.apache.org/jira/browse/THRIFT-5817) - Avoid copy of TUuid +- [THRIFT-5821](https://issues.apache.org/jira/browse/THRIFT-5821) - Cannot compile against aws-lc libcrypto (openssl replacement from AWS) +- [THRIFT-5841](https://issues.apache.org/jira/browse/THRIFT-5841) - possible init/deinit conflict with manual initialization flag +- [THRIFT-5853](https://issues.apache.org/jira/browse/THRIFT-5853) - Remove oldstyle casts from TBufferTransports and TCompactProtocol +- [THRIFT-5854](https://issues.apache.org/jira/browse/THRIFT-5854) - TCompactProtocol readString checks maxMessageSize at wrong position and off by one +- [THRIFT-5868](https://issues.apache.org/jira/browse/THRIFT-5868) - UUID Support for TCompactProtocol +- [THRIFT-5865](https://issues.apache.org/jira/browse/THRIFT-5865) - Fix TBinayProtocol with `list` + + +### Compiler (General) + +- [THRIFT-5823](https://issues.apache.org/jira/browse/THRIFT-5823) - Fix illegal uses of exceptions as normal struct type +- [THRIFT-5835](https://issues.apache.org/jira/browse/THRIFT-5835) - Allow exceptions to be used as regular struct datatype + +### Delphi + +- [THRIFT-5822](https://issues.apache.org/jira/browse/THRIFT-5822) - Remove deprecated AnsiString functions from the library +- [THRIFT-5824](https://issues.apache.org/jira/browse/THRIFT-5824) - Migrate, refactor and improve Delphi code generation test script +- [THRIFT-5825](https://issues.apache.org/jira/browse/THRIFT-5825) - UUID constants lead to uncompileable Delphi code +- [THRIFT-5826](https://issues.apache.org/jira/browse/THRIFT-5826) - binary constants create uncompilable Delphi code +- [THRIFT-5827](https://issues.apache.org/jira/browse/THRIFT-5827) - enums in typedefs are not resolved in all cases +- [THRIFT-5837](https://issues.apache.org/jira/browse/THRIFT-5837) - Delphi implementation for THRIFT-5835 +- [THRIFT-5839](https://issues.apache.org/jira/browse/THRIFT-5839) - incorrect cast under Win64 +- [THRIFT-5850](https://issues.apache.org/jira/browse/THRIFT-5850) - Switch IThriftConfiguration interface from Cardinal to Integer +- [THRIFT-5851](https://issues.apache.org/jira/browse/THRIFT-5851) - Promote known total stream sizes for seekable stream transports properly +- [THRIFT-5856](https://issues.apache.org/jira/browse/THRIFT-5856) - Client should validate HTTP status + +### Go + +- [THRIFT-5833](https://issues.apache.org/jira/browse/THRIFT-5833) - go: Combine I/O and original error in compiler generated Process functions +- [THRIFT-5845](https://issues.apache.org/jira/browse/THRIFT-5845) - The write error for union fields should be TException +- [THRIFT-5859](https://issues.apache.org/jira/browse/THRIFT-5859) - go: Generate a map for know values of an enum type + +### Java + +- [THRIFT-5858](https://issues.apache.org/jira/browse/THRIFT-5858) - Introduce new type MESSAGE_SIZE_LIMIT in TTransportException + +### netstd + +- [THRIFT-5832](https://issues.apache.org/jira/browse/THRIFT-5832) - Drop net6 support and add net9 instead +- [THRIFT-5838](https://issues.apache.org/jira/browse/THRIFT-5838) - THttpTransport.FlushAsync does not include original exception +- [THRIFT-5852](https://issues.apache.org/jira/browse/THRIFT-5852) - Promote known total stream sizes for seekable stream transports + +### Node.js + +- [THRIFT-5811](https://issues.apache.org/jira/browse/THRIFT-5811) - Add ES module support to JS codegen +- [THRIFT-5848](https://issues.apache.org/jira/browse/THRIFT-5848) - Expose InputBufferUnderrunError in nodejs client +- [THRIFT-5849](https://issues.apache.org/jira/browse/THRIFT-5849) - Expose createClient in browser version of nodejs package + +### PHP + +- [THRIFT-1482](https://issues.apache.org/jira/browse/THRIFT-1482) - Unix domain socket support under PHP +- [THRIFT-5829](https://issues.apache.org/jira/browse/THRIFT-5829) - PHP lib Use of "static" in callables is deprecated notice + +### Python + +- [THRIFT-5024](https://issues.apache.org/jira/browse/THRIFT-5024) - tutorial\py.tornado\PythonServer.py failed under Tornado6 +- [THRIFT-5847](https://issues.apache.org/jira/browse/THRIFT-5847) - Python3.12 deprecation in THttpClient +- [THRIFT-5857](https://issues.apache.org/jira/browse/THRIFT-5857) - Remove deprecated Tornado io_loop usage +- [THRIFT-5861](https://issues.apache.org/jira/browse/THRIFT-5861) - Add isOpen method to TTornadoStreamTransport + +### Swift + +- [THRIFT-4838](https://issues.apache.org/jira/browse/THRIFT-4838) - add unix domain socket support to Swift TSocketTransport implementation + + +## 0.21.0 + +### Build Process + +- [THRIFT-5815](https://issues.apache.org/jira/browse/THRIFT-5815) - veralign.sh broken and incomplete +- [THRIFT-5810](https://issues.apache.org/jira/browse/THRIFT-5810) - Wrong installation path for static MSVC libs. +- [THRIFT-5755](https://issues.apache.org/jira/browse/THRIFT-5755) - Docker image build fail + +### C++ + +- [THRIFT-5272](https://issues.apache.org/jira/browse/THRIFT-5272) - printTo does not properly handle i8 datatypes +- [THRIFT-5492](https://issues.apache.org/jira/browse/THRIFT-5492) - Bogus END_OF_FILE exception +- [THRIFT-5678](https://issues.apache.org/jira/browse/THRIFT-5678) - TConnectedClient: warning due to non-virtual dtor +- [THRIFT-5682](https://issues.apache.org/jira/browse/THRIFT-5682) - UB in generated C++ code stops compiling with C++20" +- [THRIFT-5709](https://issues.apache.org/jira/browse/THRIFT-5709) - Drastically improve `to_num()` performace +- [THRIFT-5772](https://issues.apache.org/jira/browse/THRIFT-5772) - Add UUID support for C++ +- [THRIFT-5773](https://issues.apache.org/jira/browse/THRIFT-5773) - UUID wrapper for C++ +- [THRIFT-5816](https://issues.apache.org/jira/browse/THRIFT-5816) - Fix UUID for boost 1.86.0 (change in data member usage) + +### Compiler (General) + +- [THRIFT-5800](https://issues.apache.org/jira/browse/THRIFT-5800) - "Could not find include file foo.thrift" probably should be failure instead of warning +- [THRIFT-5766](https://issues.apache.org/jira/browse/THRIFT-5766) - Replace std::endl with "\n" + +### Delphi + +- [THRIFT-5789](https://issues.apache.org/jira/browse/THRIFT-5789) - Refactor test suite client implementation +- [THRIFT-5782](https://issues.apache.org/jira/browse/THRIFT-5782) - implement full deprecation support +- [THRIFT-5750](https://issues.apache.org/jira/browse/THRIFT-5750) - Remove "ansistr_binary_" option +- [THRIFT-5788](https://issues.apache.org/jira/browse/THRIFT-5788) - Refactor and streamline hash set implementation +- [THRIFT-5765](https://issues.apache.org/jira/browse/THRIFT-5765) - Extra override for WriteBinary() to avoid unnecessary memory allocations when using COM types +- [THRIFT-5764](https://issues.apache.org/jira/browse/THRIFT-5764) - Extra CTOR for TThriftBytesImpl + +### Go + +- [THRIFT-5786](https://issues.apache.org/jira/browse/THRIFT-5786) - Full deprecation support for go +- [THRIFT-5654](https://issues.apache.org/jira/browse/THRIFT-5654) - LNK4042 and LNK2019 in go_validator_generator.cc +- [THRIFT-5784](https://issues.apache.org/jira/browse/THRIFT-5784) - go: Add THeaderTransforms to TConfiguration + +### Java + +- [THRIFT-5762](https://issues.apache.org/jira/browse/THRIFT-5762) - Expose service result objects in Java +- [THRIFT-5530](https://issues.apache.org/jira/browse/THRIFT-5530) - could not resolve plugin artifact 'com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:4.0.4' +- [THRIFT-5230](https://issues.apache.org/jira/browse/THRIFT-5230) - Fix connection leak and CancelledKeyException when handling Epoll bug +- [THRIFT-4847](https://issues.apache.org/jira/browse/THRIFT-4847) - CancelledKeyException causes TThreadedSelectorServer to fail. + +### JSON + +- [THRIFT-5761](https://issues.apache.org/jira/browse/THRIFT-5761) - Lib/json tests fail + +### netstd + +- [THRIFT-5798](https://issues.apache.org/jira/browse/THRIFT-5798) - Expand netstd compile tests to fully cover all current target environments +- [THRIFT-5797](https://issues.apache.org/jira/browse/THRIFT-5797) - HashSet() CTOR takes no argument for net < 5 +- [THRIFT-5796](https://issues.apache.org/jira/browse/THRIFT-5796) - Indicate target environment via #if check +- [THRIFT-5795](https://issues.apache.org/jira/browse/THRIFT-5795) - namespace not properly escaped +- [THRIFT-5794](https://issues.apache.org/jira/browse/THRIFT-5794) - Uncompilable C# code in 0.20.0 +- [THRIFT-5781](https://issues.apache.org/jira/browse/THRIFT-5781) - implement full deprecation support +- [THRIFT-5780](https://issues.apache.org/jira/browse/THRIFT-5780) - Prevent certain warnings related to net8 +- [THRIFT-5787](https://issues.apache.org/jira/browse/THRIFT-5787) - .NET ApacheThrift client v20.0 breaks compatibility in TBinaryProtocol.Factory constructor +- [THRIFT-5783](https://issues.apache.org/jira/browse/THRIFT-5783) - drop net7 support + +### Node.js + +- [THRIFT-5769](https://issues.apache.org/jira/browse/THRIFT-5769) - Large messages crash Node.js client when using TFramedTransport + +### PHP + +- [THRIFT-5760](https://issues.apache.org/jira/browse/THRIFT-5760) - Update minimal version of php +- [THRIFT-5758](https://issues.apache.org/jira/browse/THRIFT-5758) - PHP 8.2 Deprecate dynamic properties +- [THRIFT-5756](https://issues.apache.org/jira/browse/THRIFT-5756) - Run php tests in github actions + +### Python + +- [THRIFT-4181](https://issues.apache.org/jira/browse/THRIFT-4181) - PEP 484 Type Hinting on generated code +- [THRIFT-5813](https://issues.apache.org/jira/browse/THRIFT-5813) - Clarify TSocket state after isOpen +- [THRIFT-5777](https://issues.apache.org/jira/browse/THRIFT-5777) - timeout exception mismatched +- [THRIFT-5139](https://issues.apache.org/jira/browse/THRIFT-5139) - Type hinting for Python library + +### Rust + +- [THRIFT-5812](https://issues.apache.org/jira/browse/THRIFT-5812) - Capacity overflow in Rust server + + ## 0.20.0 ### Known Open Issues (Blocker or Critical) @@ -421,7 +585,7 @@ NB. CL had been finally dropped from 0.17.0 due to lack of active maintainers. I ### Go -- [THRIFT-5461](https://issues.apache.org/jira/browse/THRIFT-5461) - Invalid golang code generated for optional set with a default value +- [THRIFT-5461](https://issues.apache.org/jira/browse/THRIFT-5461) - Invalid golang code generated for optional `set` with a default value - [THRIFT-5469](https://issues.apache.org/jira/browse/THRIFT-5469) - Go lib skip map value may cause stack overflow - [THRIFT-5490](https://issues.apache.org/jira/browse/THRIFT-5490) - Improve memory efficiency in go THeader implementation - [THRIFT-5509](https://issues.apache.org/jira/browse/THRIFT-5509) - Potential connection leaks caused by the connectivity check @@ -798,13 +962,13 @@ NB. CL had been finally dropped from 0.17.0 due to lack of active maintainers. I - [THRIFT-5012](https://issues.apache.org/jira/browse/THRIFT-5012) - Centralize configuration aspects into a commonly used configuration object - [THRIFT-5015](https://issues.apache.org/jira/browse/THRIFT-5015) - WinHTTP QueryDataAvailable cannot be used to retrieve total response size - [THRIFT-5036](https://issues.apache.org/jira/browse/THRIFT-5036) - buffered transport over sockets may run into unexpected timeouts -- [THRIFT-5048](https://issues.apache.org/jira/browse/THRIFT-5048) - EnumUtils.ToString() throws for elements not known to the receiving end +- [THRIFT-5048](https://issues.apache.org/jira/browse/THRIFT-5048) - `EnumUtils.ToString()` throws for elements not known to the receiving end - [THRIFT-5088](https://issues.apache.org/jira/browse/THRIFT-5088) - Memory leak in TEndpointTransportBase - [THRIFT-5123](https://issues.apache.org/jira/browse/THRIFT-5123) - add possibility to query HTTP status code with WinHTTP - [THRIFT-5146](https://issues.apache.org/jira/browse/THRIFT-5146) - Align Delphi to the test suite arguments rules (its "--switch=value", not "--switch value") - [THRIFT-5186](https://issues.apache.org/jira/browse/THRIFT-5186) - AI_ADDRCONFIG: Thrift libraries crash with localhost-only network. - [THRIFT-5188](https://issues.apache.org/jira/browse/THRIFT-5188) - Occasional ERROR_INSUFFICIENT_BUFFER at WinHttpQueryHeaders() -- [THRIFT-5251](https://issues.apache.org/jira/browse/THRIFT-5251) - StringUtils.ToString() raises an exception for enum values outside range +- [THRIFT-5251](https://issues.apache.org/jira/browse/THRIFT-5251) - `StringUtils.ToString()` raises an exception for enum values outside range - [THRIFT-5304](https://issues.apache.org/jira/browse/THRIFT-5304) - TWinHTTPClientImpl may incorrectly report that the message size is reached ### Documentation @@ -1129,7 +1293,7 @@ NB. CL had been finally dropped from 0.17.0 due to lack of active maintainers. I - [THRIFT-4884](https://issues.apache.org/jira/browse/THRIFT-4884) - Add serialisation performance test for Delphi - [THRIFT-4886](https://issues.apache.org/jira/browse/THRIFT-4886) - More detailed error information for WinHTTP transport - [THRIFT-4894](https://issues.apache.org/jira/browse/THRIFT-4894) - Enable automatic content encoding handling for gzip,deflate in the WinHTTP client -- [THRIFT-4939](https://issues.apache.org/jira/browse/THRIFT-4939) - TThriftListImpl.Sort() does not use comparer +- [THRIFT-4939](https://issues.apache.org/jira/browse/THRIFT-4939) - `TThriftListImpl.Sort()` does not use comparer - [THRIFT-4944](https://issues.apache.org/jira/browse/THRIFT-4944) - Field IDs > 255 fail with compact protocol ### Documentation @@ -1338,7 +1502,7 @@ Released 2019-JAN-04 - [THRIFT-4384](https://issues.apache.org/jira/browse/THRIFT-4384) - cpp: Using multiple async services simultaneously is not thread-safe - [THRIFT-3108](https://issues.apache.org/jira/browse/THRIFT-3108) - haskell: Defaulted struct parameters on a service generates invalid Haskell - [THRIFT-3990](https://issues.apache.org/jira/browse/THRIFT-3990) - nodejs: Exception swallowed by deserialization function -- [THRIFT-4214](https://issues.apache.org/jira/browse/THRIFT-4214) - nodejs: map key treated as hex value in JavaScript +- [THRIFT-4214](https://issues.apache.org/jira/browse/THRIFT-4214) - nodejs: `map` key treated as hex value in JavaScript - [THRIFT-4602](https://issues.apache.org/jira/browse/THRIFT-4602) - nodejs: ERROR in ./node_modules/thrift/lib/nodejs/lib/thrift/connection.js Module not found: Error: Can't resolve 'child_process' - [THRIFT-4639](https://issues.apache.org/jira/browse/THRIFT-4639) - nodejs: Sequence numbering for multiplexed protocol broken - [THRIFT-1310](https://issues.apache.org/jira/browse/THRIFT-1310) - php: sequence and reconnection management issues @@ -1617,7 +1781,7 @@ Released 2017-DEC-27 - [THRIFT-3891](https://issues.apache.org/jira/browse/THRIFT-3891) - TNonblockingServer configured with more than one IO threads does not always return from serve() upon stop() - [THRIFT-3892](https://issues.apache.org/jira/browse/THRIFT-3892) - Thrift uses TLS SNI extension provided by OpenSSL library. Older version of OpenSSL(< 0.9.8f) may create problem because they do not support 'SSL_set_tlsext_host_name()'. - [THRIFT-3895](https://issues.apache.org/jira/browse/THRIFT-3895) - Build fails using Java 1.8 with Ant < 1.9 -- [THRIFT-3896](https://issues.apache.org/jira/browse/THRIFT-3896) - map data with number string key cannot access that deserialized by php extension +- [THRIFT-3896](https://issues.apache.org/jira/browse/THRIFT-3896) - `map` data with number string key cannot access that deserialized by php extension - [THRIFT-3938](https://issues.apache.org/jira/browse/THRIFT-3938) - Python TNonblockingServer does not work with SSL - [THRIFT-3944](https://issues.apache.org/jira/browse/THRIFT-3944) - TSSLSocket has dead code in checkHandshake - [THRIFT-3946](https://issues.apache.org/jira/browse/THRIFT-3946) - Java 1.5 compatibility broken for binary fields (java5 option) @@ -2013,8 +2177,8 @@ Released 2017-DEC-27 - [THRIFT-3635](https://issues.apache.org/jira/browse/THRIFT-3635) - D transport_test is flaky on Jenkins and Travis - [THRIFT-3618](https://issues.apache.org/jira/browse/THRIFT-3618) - Python TSSLSocket deprecation message should print caller's location - [THRIFT-3145](https://issues.apache.org/jira/browse/THRIFT-3145) - JSON protocol does not handle bool and empty containers correctly -- [THRIFT-3158](https://issues.apache.org/jira/browse/THRIFT-3158) - TBase#deepCopy should return T -- [THRIFT-3157](https://issues.apache.org/jira/browse/THRIFT-3157) - TBase signature should be TBase, F extends TFieldIdEnum> +- [THRIFT-3158](https://issues.apache.org/jira/browse/THRIFT-3158) - `TBase#deepCopy` should return T +- [THRIFT-3157](https://issues.apache.org/jira/browse/THRIFT-3157) - TBase signature should be `TBase, F extends TFieldIdEnum>` - [THRIFT-3156](https://issues.apache.org/jira/browse/THRIFT-3156) - Node TLS: server executes processing logic two full times - [THRIFT-3154](https://issues.apache.org/jira/browse/THRIFT-3154) - tutorial/py.tornado throw EOF exception - [THRIFT-3063](https://issues.apache.org/jira/browse/THRIFT-3063) - C++ build -Wunused-parameter warnings on processor_test, TransportTest @@ -2051,7 +2215,7 @@ Released 2017-DEC-27 - [THRIFT-3392](https://issues.apache.org/jira/browse/THRIFT-3392) - Java TZlibTransport does not close its wrapper streams upon close() - [THRIFT-3383](https://issues.apache.org/jira/browse/THRIFT-3383) - i64 related warnings - [THRIFT-3386](https://issues.apache.org/jira/browse/THRIFT-3386) - misc. warnings with make check -- [THRIFT-3385](https://issues.apache.org/jira/browse/THRIFT-3385) - warning: format ‘%lu’ expects ‘long unsigned int’, but has type ‘std::basic_string::size_type {aka unsigned int} +- [THRIFT-3385](https://issues.apache.org/jira/browse/THRIFT-3385) - warning: format ‘%lu’ expects ‘long unsigned int’, but has type `std::basic_string::size_type {aka unsigned int}` - [THRIFT-3355](https://issues.apache.org/jira/browse/THRIFT-3355) - npm WARN package.json thrift@1.0.0-dev No license field. - [THRIFT-3360](https://issues.apache.org/jira/browse/THRIFT-3360) - Improve cross test servers and clients further - [THRIFT-3359](https://issues.apache.org/jira/browse/THRIFT-3359) - Binary field incompatibilities @@ -2070,7 +2234,7 @@ Released 2017-DEC-27 - [THRIFT-3564](https://issues.apache.org/jira/browse/THRIFT-3564) - C++/Qt: potential core dump in TQTcpServer in case an exception occurs in TAsyncProcessor::process() - [THRIFT-3558](https://issues.apache.org/jira/browse/THRIFT-3558) - typos in c_glib tests - [THRIFT-3559](https://issues.apache.org/jira/browse/THRIFT-3559) - Fix awkward extra semi-colons with Cocoa container literals -- [THRIFT-3555](https://issues.apache.org/jira/browse/THRIFT-3555) - 'configure' script does not honor --with-openssl= for libcrypto for BN_init +- [THRIFT-3555](https://issues.apache.org/jira/browse/THRIFT-3555) - 'configure' script does not honor `--with-openssl=` for libcrypto for BN_init - [THRIFT-3554](https://issues.apache.org/jira/browse/THRIFT-3554) - Constant decls may lead to "Error: internal error: prepare_member_name_mapping() already active for different struct" - [THRIFT-3552](https://issues.apache.org/jira/browse/THRIFT-3552) - glib_c Memory Leak - [THRIFT-3551](https://issues.apache.org/jira/browse/THRIFT-3551) - Thrift perl library missing package declaration @@ -2127,7 +2291,7 @@ Released 2017-DEC-27 - [THRIFT-3413](https://issues.apache.org/jira/browse/THRIFT-3413) - Thrift code generation bug in Go when extending service - [THRIFT-3420](https://issues.apache.org/jira/browse/THRIFT-3420) - C++: TSSLSockets are not interruptable - [THRIFT-3415](https://issues.apache.org/jira/browse/THRIFT-3415) - include unistd.h conditionally -- [THRIFT-3414](https://issues.apache.org/jira/browse/THRIFT-3414) - #include in THeaderTransport.h breaks windows build +- [THRIFT-3414](https://issues.apache.org/jira/browse/THRIFT-3414) - `#include ` in THeaderTransport.h breaks windows build - [THRIFT-3411](https://issues.apache.org/jira/browse/THRIFT-3411) - Go generates remotes with wrong package qualifiers when including - [THRIFT-3430](https://issues.apache.org/jira/browse/THRIFT-3430) - Go THttpClient does not read HTTP response body to completion when closing - [THRIFT-3423](https://issues.apache.org/jira/browse/THRIFT-3423) - First call to thrift_transport:read_exact fails to dispatch correct function @@ -2234,11 +2398,11 @@ Released 2017-DEC-27 - [THRIFT-2821](https://issues.apache.org/jira/browse/THRIFT-2821) - Enable the use of custom HTTP-Header in the Transport - [THRIFT-2093](https://issues.apache.org/jira/browse/THRIFT-2093) - added the ability to set compression level in C++ zlib transport - [THRIFT-2089](https://issues.apache.org/jira/browse/THRIFT-2089) - Compiler ignores duplicate typenames -- [THRIFT-2056](https://issues.apache.org/jira/browse/THRIFT-2056) - Moved all #include config.h statements to #include +- [THRIFT-2056](https://issues.apache.org/jira/browse/THRIFT-2056) - Moved all #include config.h statements to #include `` - [THRIFT-2031](https://issues.apache.org/jira/browse/THRIFT-2031) - Make SO_KEEPALIVE configurable for C++ lib - [THRIFT-2021](https://issues.apache.org/jira/browse/THRIFT-2021) - Improve large binary protocol string performance - [THRIFT-2028](https://issues.apache.org/jira/browse/THRIFT-2028) - Cleanup threading headers / libraries -- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use style throughout +- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use `` style throughout - [THRIFT-2312](https://issues.apache.org/jira/browse/THRIFT-2312) - travis.yml: build everything - [THRIFT-1915](https://issues.apache.org/jira/browse/THRIFT-1915) - Multiplexing Services - [THRIFT-1736](https://issues.apache.org/jira/browse/THRIFT-1736) - Visual Studio top level project files within msvc @@ -2505,7 +2669,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-3102](https://issues.apache.org/jira/browse/THRIFT-3102) - could not make check for Go Library - [THRIFT-3120](https://issues.apache.org/jira/browse/THRIFT-3120) - Minor spelling errors and an outdated URL - [THRIFT-3121](https://issues.apache.org/jira/browse/THRIFT-3121) - Librt does not exist on OS X -- [THRIFT-3152](https://issues.apache.org/jira/browse/THRIFT-3152) - Compiler error on Mac OSX (missing #include ) +- [THRIFT-3152](https://issues.apache.org/jira/browse/THRIFT-3152) - Compiler error on Mac OSX (missing `#include `) - [THRIFT-3162](https://issues.apache.org/jira/browse/THRIFT-3162) - make fails for dmd 2.067 - [THRIFT-3164](https://issues.apache.org/jira/browse/THRIFT-3164) - Thrift C++ library SSL socket by default allows for unsecure SSLv3 negotiation - [THRIFT-3168](https://issues.apache.org/jira/browse/THRIFT-3168) - Fix Maven POM @@ -2613,7 +2777,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-2864](https://issues.apache.org/jira/browse/THRIFT-2864) - JSON generator missing from Visual Studio build project - [THRIFT-2878](https://issues.apache.org/jira/browse/THRIFT-2878) - Go validation support of required fields - [THRIFT-2873](https://issues.apache.org/jira/browse/THRIFT-2873) - TPipe and TPipeServer don't compile on Windows with UNICODE enabled -- [THRIFT-2888](https://issues.apache.org/jira/browse/THRIFT-2888) - import of is missing in JSON generator +- [THRIFT-2888](https://issues.apache.org/jira/browse/THRIFT-2888) - import of `` is missing in JSON generator - [THRIFT-2900](https://issues.apache.org/jira/browse/THRIFT-2900) - Python THttpClient does not reset socket timeout on exception - [THRIFT-2907](https://issues.apache.org/jira/browse/THRIFT-2907) - 'ntohll' macro redefined - [THRIFT-2884](https://issues.apache.org/jira/browse/THRIFT-2884) - Map does not serialize correctly for JSON protocol in Go library @@ -2892,7 +3056,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. ### Bug - [THRIFT-2793](https://issues.apache.org/jira/browse/THRIFT-2793) - Go compiler produces uncompilable code - [THRIFT-1481](https://issues.apache.org/jira/browse/THRIFT-1481) - Unix domain sockets in C++ do not support the abstract namespace -- [THRIFT-1455](https://issues.apache.org/jira/browse/THRIFT-1455) - TBinaryProtocolT::writeString casts from size_t to uint32_t, which is not safe on 64-bit platforms +- [THRIFT-1455](https://issues.apache.org/jira/browse/THRIFT-1455) - `TBinaryProtocolT::writeString` casts from size_t to uint32_t, which is not safe on 64-bit platforms - [THRIFT-1579](https://issues.apache.org/jira/browse/THRIFT-1579) - PHP Extension) - function thrift_protocol_read_binary not working from TBinarySerializer::deserialize - [THRIFT-1584](https://issues.apache.org/jira/browse/THRIFT-1584) - Error: could not SetMinThreads in ThreadPool on single-core machines - [THRIFT-1614](https://issues.apache.org/jira/browse/THRIFT-1614) - Thrift build from svn repo sources fails with automake-1.12 @@ -2985,7 +3149,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-2389](https://issues.apache.org/jira/browse/THRIFT-2389) - namespaces handled wrongly in acrionscript 3.0 implementation - [THRIFT-2388](https://issues.apache.org/jira/browse/THRIFT-2388) - GoLang) - Fix data races in simple_server and server_socket - [THRIFT-2386](https://issues.apache.org/jira/browse/THRIFT-2386) - Thrift refuses to link yylex -- [THRIFT-2375](https://issues.apache.org/jira/browse/THRIFT-2375) - Excessive
's in generated HTML +- [THRIFT-2375](https://issues.apache.org/jira/browse/THRIFT-2375) - Excessive `
`'s in generated HTML - [THRIFT-2373](https://issues.apache.org/jira/browse/THRIFT-2373) - warning CS0414 in THttpClient.cs: private field 'Thrift.Transport.THttpClient.connection' assigned but never used - [THRIFT-2372](https://issues.apache.org/jira/browse/THRIFT-2372) - thrift/json_protocol.go:160: function ends without a return statement - [THRIFT-2371](https://issues.apache.org/jira/browse/THRIFT-2371) - ruby bundler version fails on ~1.3.1, remove and take latest avail @@ -3179,7 +3343,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-2401](https://issues.apache.org/jira/browse/THRIFT-2401) - Haskell tutorial compiles - [THRIFT-2417](https://issues.apache.org/jira/browse/THRIFT-2417) - C# Union classes are not partial - [THRIFT-2415](https://issues.apache.org/jira/browse/THRIFT-2415) - Named pipes server performance & message mode -- [THRIFT-2404](https://issues.apache.org/jira/browse/THRIFT-2404) - emit warning on (typically inefficient) list +- [THRIFT-2404](https://issues.apache.org/jira/browse/THRIFT-2404) - emit warning on (typically inefficient) `list` - [THRIFT-2398](https://issues.apache.org/jira/browse/THRIFT-2398) - Improve Node Server Library - [THRIFT-2397](https://issues.apache.org/jira/browse/THRIFT-2397) - Add CORS and CSP support for JavaScript and Node.js libraries - [THRIFT-2407](https://issues.apache.org/jira/browse/THRIFT-2407) - use markdown (rename README => README.md) @@ -3430,7 +3594,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-990](https://issues.apache.org/jira/browse/THRIFT-990) - Sanify gettimeofday usage codebase-wide - [THRIFT-791](https://issues.apache.org/jira/browse/THRIFT-791) - Let C++ TSimpleServer be driven by an external main loop - [THRIFT-2117](https://issues.apache.org/jira/browse/THRIFT-2117) - Cocoa TBinaryProtocol strictWrite should be set to true by default -- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use style throughout +- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use `` style throughout - [THRIFT-1972](https://issues.apache.org/jira/browse/THRIFT-1972) - Add support for async processors - [THRIFT-1970](https://issues.apache.org/jira/browse/THRIFT-1970) - [Graphviz] Adds option to render exceptions relationships - [THRIFT-1966](https://issues.apache.org/jira/browse/THRIFT-1966) - Support different files for SSL certificates and keys @@ -3550,7 +3714,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-1553](https://issues.apache.org/jira/browse/THRIFT-1553) - thrift nodejs service side can't read map structure, key as enum, value as Object - [THRIFT-1575](https://issues.apache.org/jira/browse/THRIFT-1575) - Typo in server/TThreadPoolServer.h - [THRIFT-1327](https://issues.apache.org/jira/browse/THRIFT-1327) - Fix Spec Suite under Ruby-1.8.7 (works for MRI Ruby-1.9.2) -- [THRIFT-1326](https://issues.apache.org/jira/browse/THRIFT-1326) - on some platforms, #include is necessary to be included in Thrift.h +- [THRIFT-1326](https://issues.apache.org/jira/browse/THRIFT-1326) - on some platforms, `#include ` is necessary to be included in Thrift.h - [THRIFT-1159](https://issues.apache.org/jira/browse/THRIFT-1159) - THttpClient->Flush() issue (connection thru proxy) - [THRIFT-1277](https://issues.apache.org/jira/browse/THRIFT-1277) - Node.js serializes false booleans as null - [THRIFT-1224](https://issues.apache.org/jira/browse/THRIFT-1224) - Cannot insert UTF-8 text @@ -3838,7 +4002,7 @@ Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release. - [THRIFT-1192](https://issues.apache.org/jira/browse/THRIFT-1192) - Typo: TProtocol.h tests for HAVE_SYS_PARAM_H_ - [THRIFT-1190](https://issues.apache.org/jira/browse/THRIFT-1190) - readBufferBytesAllocated in TNonblockingServer.java should be AtomicLong to fix FD leakage and general server malfunction - [THRIFT-1187](https://issues.apache.org/jira/browse/THRIFT-1187) - nonblocking_server shutdown race under Ruby 1.9 -- [THRIFT-1178](https://issues.apache.org/jira/browse/THRIFT-1178) - Java: TBase signature should be T extends TBase +- [THRIFT-1178](https://issues.apache.org/jira/browse/THRIFT-1178) - Java: TBase signature should be `T extends TBase` - [THRIFT-1164](https://issues.apache.org/jira/browse/THRIFT-1164) - Segmentation fault on NULL pointer in t_js_generator::generate_const - [THRIFT-1171](https://issues.apache.org/jira/browse/THRIFT-1171) - Perl write/readDouble assumes little-endian platform - [THRIFT-1222](https://issues.apache.org/jira/browse/THRIFT-1222) - Unhandled exception for TEvhttpServer request diff --git a/CMakeLists.txt b/CMakeLists.txt index a685e4f3705..fc11ec2323e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ # under the License. # -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.16) if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) # package version behavior added in cmake 3.0 @@ -28,14 +28,14 @@ endif() # PACKAGE_VERSION is used by cpack scripts currently # Both thrift_VERSION and PACKAGE_VERSION should be the same for now -set(thrift_VERSION "0.20.0") +set(thrift_VERSION "0.23.0") set(PACKAGE_VERSION ${thrift_VERSION}) project("thrift" VERSION ${PACKAGE_VERSION}) message(STATUS "Configuring ${CMAKE_PROJECT_NAME} ${thrift_VERSION}") -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake") +list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake") # Some default settings include(DefineCMakeDefaults) diff --git a/FUZZING.md b/FUZZING.md new file mode 100644 index 00000000000..146b015edfb --- /dev/null +++ b/FUZZING.md @@ -0,0 +1,78 @@ +# Fuzzing Apache Thrift + +This document describes the fuzzing infrastructure and goals for Apache Thrift. + +We use [OSS-Fuzz](https://github.com/google/oss-fuzz) as our primary fuzzing platform to continuously test and improve the robustness of Thrift's hand-written and generated code. + +## Goals + +With fuzzing, we are focusing on testing the following key aspects across supported languages: + +1. Security - Testing how the generated code handles malformed/malicious input +2. Serialization round-trip correctness - Ensuring that data stays identical if we serialize then deserialize it. + +## Supported Languages + +We currently maintain fuzzers for the following languages: + +- Go +- c_glib (partially supported, needs round-trip support) +- C++ +- Java/JVM (and other JVM languages) +- JavaScript +- Python +- Rust +- Swift + +We are working on adding fuzzers for the following languages: + +- netstd + +## Fuzzer Types + +For each supported language, we implement at minimum: + +1. **Deserializer Fuzzer** + - Takes raw fuzzer input and attempts to deserialize it into Thrift structures + - Tests handling of malformed/unexpected input + - Implemented for each supported protocol (Binary, Compact, JSON where available) + +2. **Round-Trip Fuzzer** + - Deserializes fuzzer input, then re-serializes and verifies it matches + - Ensures data integrity through serialization cycles + - Tests both serialization and deserialization code paths + +## Building and Running the Fuzzers + +Each language has its own fuzzers under the `lib//test/fuzz` directory. +The fuzzers are built when building the language-specific code (using the normal build system), as regular binaries (without fuzzing support enabled), to ensure that there are no build breakages. + +To ensure fuzzing can find issues as soon as possible, we will enable fuzzing support in CI once the fuzzers are stable. + +Currently the only convenient, formally supported build with fuzzing support enabled is the via the oss-fuzz workflow. For languages where local fuzzing is easy to do, documentation is provided along with the fuzzers. + +## OSS-Fuzz Integration + +Our fuzzers run continuously on OSS-Fuzz. To view build status: + +1. Visit the [OSS-Fuzz Status Dashboard](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) +2. Look for the "thrift" project + +The source code for the oss-fuzz build is [available upstream](https://github.com/google/oss-fuzz/tree/master/projects/thrift). + +We aim to improve the fuzzers through viewing the fuzz introspector reports, available [here](https://introspector.oss-fuzz.com/project-profile?project=thrift). + +*NB: The oss-fuzz integration will be significantly updated once all the language specific fuzzers are committed here. + +## Contributing to the fuzzers + +To contribute to the fuzzing effort - please look at https://issues.apache.org/jira/browse/THRIFT-5855 for the latest status and planned work. Once the ticket is closed, +we would still appreciate contributions that: + +1. Add new fuzzers for unsupported languages +2. Improve existing fuzzers +3. Add test cases to corpus + +If you do add or change a fuzzer, please remember to make corresponding changes to the oss-fuzz build script in case they are needed. + +Please see CONTRIBUTING.md for general contribution guidelines. \ No newline at end of file diff --git a/LANGUAGES.md b/LANGUAGES.md index 4952ade158b..baed8cec302 100644 --- a/LANGUAGES.md +++ b/LANGUAGES.md @@ -1,6 +1,11 @@ # Apache Thrift Language Support # -Guidance For: 0.17.0 | +Guidance For: 0.22.0 | +[0.21.0](https://github.com/apache/thrift/blob/v0.21.0/LANGUAGES.md) | +[0.20.0](https://github.com/apache/thrift/blob/v0.20.0/LANGUAGES.md) | +[0.19.0](https://github.com/apache/thrift/blob/v0.19.0/LANGUAGES.md) | +[0.18.0](https://github.com/apache/thrift/blob/v0.18.0/LANGUAGES.md) | +[0.17.0](https://github.com/apache/thrift/blob/v0.17.0/LANGUAGES.md) | [0.16.0](https://github.com/apache/thrift/blob/v0.16.0/LANGUAGES.md) | [0.15.0](https://github.com/apache/thrift/blob/v0.15.0/LANGUAGES.md) | [0.14.0](https://github.com/apache/thrift/blob/v0.14.0/LANGUAGES.md) | @@ -80,7 +85,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.2.0 YesYes C++11 - +Yes YesYesYesYesYesYes YesYesYesYes YesYesYesYes @@ -127,25 +132,25 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Delphi 0.8.0 -2010Alexandria 11.2 +2010Athens 12.2 Yes -Yes +YesYesYesYes YesYes YesYesYesYes Yes Delphi -.NET Standard +.NET 0.13.0 Yes -.NET Standard 2.x, .NET 6 +.NET Standard 2.x, net8, net9 Yes YesYesYesYes YesYes YesYesYesYes Yes -.NET Standard +.NET Erlang @@ -163,9 +168,9 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Go 0.7.0 Yes -1.211.22 - -YesYesYes +1.241.25 +Yes +YesYesYesYes YesYesYesYes YesYesYesYes Yes @@ -176,7 +181,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.9.3 Yes 4.1.54.2.5 - +Yes YesYes YesYes YesYesYesYes @@ -247,7 +252,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr node.ts 0.12.0 Yes -3.1.6 +5.7.2 YesYes @@ -319,7 +324,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Rust 0.11.0 Yes -1.65.01.xx.x +1.83.01.xx.x YesYes Yes @@ -344,8 +349,8 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.12.0 Yes 5.7 - -YesYesYesYes +Yes +YesYesYesYesYes YesYes YesYesYes Yes @@ -359,7 +364,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr autoconfcmake MinMax Uuid -Domain File Memory Pipe Socket TLS  +Domain File Memory Pipe Socket TLS  FramedHeader http  zlib  BinaryCompact JSON Multiplex ForkingNonblockingSimpleThreadedThreadPool diff --git a/Makefile.am b/Makefile.am index 5b9e9709f2f..735cd405929 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,13 +131,14 @@ skipped_files = $(subst $(space),$(comma),$(codespell_skip_files)) style-local: codespell --write-changes --skip=$(skipped_files) --disable-colors +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ .asf.yaml \ .clang-format \ .dockerignore \ .editorconfig \ - .eslintignore \ - .eslintrc.json \ .flake8 \ .gitattributes \ .gitignore \ @@ -147,6 +148,7 @@ EXTRA_DIST = \ .github/workflows/build.yml \ .github/workflows/cmake.yml \ .github/workflows/pypi.yml \ + .github/workflows/release_rust.yml \ .travis.yml \ ApacheThrift.nuspec \ appveyor.yml \ @@ -162,6 +164,7 @@ EXTRA_DIST = \ doap.rdf \ doc \ dub.json \ + eslint.config.mjs \ go.mod \ jitpack.yml \ LANGUAGES.md \ @@ -169,6 +172,7 @@ EXTRA_DIST = \ NOTICE \ package.json \ package-lock.json \ + Package.swift \ phpcs.xml.dist \ README.md \ rust-toolchain \ diff --git a/Package.swift b/Package.swift new file mode 100644 index 00000000000..773ea0569cc --- /dev/null +++ b/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.1 +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PackageDescription + +let package = Package( + name: "Thrift", + products: [ + .library(name: "Thrift", targets: ["Thrift"]) + ], + targets: [ + .target(name: "Thrift", path: "lib/swift/Sources"), + .testTarget(name: "ThriftTests", dependencies: ["Thrift"], path: "lib/swift/Tests/ThriftTests") + ] +) diff --git a/Thrift.podspec b/Thrift.podspec index 8bf70f64f18..76ae462b008 100644 --- a/Thrift.podspec +++ b/Thrift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Thrift' - s.version = '0.20.0' + s.version = '0.23.0' s.summary = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC." s.description = <<-DESC The Apache Thrift scalable cross-language software framework for networked services development combines a software stack with a code generation engine to build services that work efficiently and seamlessly between many programming languages. @@ -10,6 +10,6 @@ The Apache Thrift scalable cross-language software framework for networked servi s.author = { 'Apache Thrift Developers' => 'dev@thrift.apache.org' } s.ios.deployment_target = '9.0' s.osx.deployment_target = '10.10' - s.source = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.20.0' } + s.source = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.23.0' } s.source_files = 'lib/swift/Sources/*.swift' end diff --git a/aclocal/ax_boost_base.m4 b/aclocal/ax_boost_base.m4 index d5403957637..4065af0d760 100644 --- a/aclocal/ax_boost_base.m4 +++ b/aclocal/ax_boost_base.m4 @@ -113,7 +113,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are found, e.g. when only header-only libraries are installed! AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) diff --git a/appveyor.yml b/appveyor.yml index 5847ea926ba..ff35d520e94 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,7 @@ # build Apache Thrift on AppVeyor - https://ci.appveyor.com -version: '0.20.0.{build}' +version: '0.23.0.{build}' shallow_clone: true diff --git a/bower.json b/bower.json index 84f3a989012..62af06a4590 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.23.0", "homepage": "https://github.com/apache/thrift.git", "authors": [ "Apache Thrift " diff --git a/build/appveyor/MSVC-appveyor-full.bat b/build/appveyor/MSVC-appveyor-full.bat index 49a3f94a0e5..2e81fd571e0 100644 --- a/build/appveyor/MSVC-appveyor-full.bat +++ b/build/appveyor/MSVC-appveyor-full.bat @@ -55,6 +55,8 @@ IF "%PROFILE%" == "MSVC2015" ( EXIT /B 1 ) +:: Put back the @ECHO since vcvars*.bat above disables it +@ECHO ON :: compiler and generator detection IF /i "%PLATFORM%" == "x64" SET GENARCH= Win64 @@ -88,10 +90,13 @@ SET WIN3P=%APPVEYOR_BUILD_FOLDER%\thirdparty IF "%PYTHON_VERSION%" == "" ( SET WITH_PYTHON=OFF + SET CMAKE_PYTHON_OPTS="" ) ELSE ( SET WITH_PYTHON=ON IF /i "%PLATFORM%" == "x64" (SET PTEXT=-x64) - SET PATH=C:\Python%PYTHON_VERSION:.=%!PTEXT!\scripts;C:\Python%PYTHON_VERSION:.=%!PTEXT!;!PATH! + SET PYTHON_ROOT=C:\Python%PYTHON_VERSION:.=%!PTEXT! + SET PATH=!PYTHON_ROOT!\scripts;!PYTHON_ROOT!;!PATH! + SET CMAKE_PYTHON_OPTS=-DPython3_FIND_STRATEGY=LOCATION -DPython3_ROOT=!PYTHON_ROOT! ) IF "%CONFIGURATION%" == "Debug" (SET ZLIB_LIB_SUFFIX=d) @@ -101,9 +106,10 @@ IF NOT "%QT_VERSION%" == "" ( SET PATH=C:\Qt\%QT_VERSION%\%PROFILE%!QTEXT!\bin;!PATH! ) - +@ECHO OFF CALL win_showenv.bat || EXIT /B MKDIR "%WIN3P%" || EXIT /B +@ECHO ON choco feature enable -n allowGlobalConfirmation || EXIT /B @@ -131,13 +137,12 @@ call build-libevent.bat || EXIT /B pip.exe ^ install backports.ssl_match_hostname ^ ipaddress ^ - six ^ tornado ^ twisted || EXIT /B :: Adobe Flex SDK 4.6 for ActionScript MKDIR "C:\Adobe\Flex\SDK\4.6" || EXIT /B -appveyor DownloadFile http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip -FileName C:\Adobe\Flex\SDK\4.6\SDK.zip || EXIT /B +appveyor DownloadFile https://fpdownload.adobe.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201B.zip -FileName C:\Adobe\Flex\SDK\4.6\SDK.zip || EXIT /B CD "C:\Adobe\Flex\SDK\4.6" || EXIT /B 7z x SDK.zip || EXIT /B SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6" @@ -179,7 +184,7 @@ cmake.exe "%SRCDIR%" ^ -DOPENSSL_USE_STATIC_LIBS=OFF ^ -DZLIB_LIBRARY="%WIN3P%\zlib-inst\lib\zlib%ZLIB_LIB_SUFFIX%.lib" ^ -DZLIB_ROOT="%WIN3P%\zlib-inst" ^ - -DWITH_PYTHON=%WITH_PYTHON% || EXIT /B + -DWITH_PYTHON=%WITH_PYTHON% %CMAKE_PYTHON_OPTS% || EXIT /B cmake.exe --build . --config "%CONFIGURATION%" || EXIT /B diff --git a/build/cmake/BoostMacros.cmake b/build/cmake/BoostMacros.cmake index ffb85af3224..61fac0356bb 100644 --- a/build/cmake/BoostMacros.cmake +++ b/build/cmake/BoostMacros.cmake @@ -17,6 +17,17 @@ # under the License. # +# CMake 4.0+ removed the FindBoost module (CMP0167). Use OLD behavior to +# preserve compatibility with existing ${Boost_LIBRARIES} usage. +if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) +endif() + +# Force using FindBoost instead of Boost's own BoostConfig.cmake. +# BoostConfig.cmake does not populate ${Boost_LIBRARIES} the same way, +# which causes linking failures on Windows. +set(Boost_NO_BOOST_CMAKE ON) + set(BOOST_MINREV 1.56) macro(REQUIRE_BOOST_HEADERS) diff --git a/build/cmake/DefineInstallationPaths.cmake b/build/cmake/DefineInstallationPaths.cmake index 23962b442d0..0c3dd094ac7 100644 --- a/build/cmake/DefineInstallationPaths.cmake +++ b/build/cmake/DefineInstallationPaths.cmake @@ -20,7 +20,9 @@ # Define the default install paths set(BIN_INSTALL_DIR "bin" CACHE PATH "The binary install dir (default: bin)") -if(MSVC) +# For MSVC builds, install shared libs to bin/, while keeping the install +# dir for static libs as lib/. +if(MSVC AND BUILD_SHARED_LIBS) set(LIB_INSTALL_DIR "bin${LIB_SUFFIX}" CACHE PATH "The library install dir (default: bin${LIB_SUFFIX})") else() set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The library install dir (default: lib${LIB_SUFFIX})") diff --git a/build/cmake/DefineOptions.cmake b/build/cmake/DefineOptions.cmake index b59292cd3b9..928e19b165d 100644 --- a/build/cmake/DefineOptions.cmake +++ b/build/cmake/DefineOptions.cmake @@ -87,7 +87,7 @@ CMAKE_DEPENDENT_OPTION(BUILD_C_GLIB "Build C (GLib) library" ON # OpenSSL if(WITH_CPP OR WITH_C_GLIB) - find_package(OpenSSL QUIET) + find_package(OpenSSL) CMAKE_DEPENDENT_OPTION(WITH_OPENSSL "Build with OpenSSL support" ON "OPENSSL_FOUND" OFF) endif() @@ -117,10 +117,13 @@ CMAKE_DEPENDENT_OPTION(BUILD_NODEJS "Build NodeJS library" ON # Python option(WITH_PYTHON "Build Python Thrift library" ON) -find_package(PythonInterp QUIET) # for Python executable -find_package(PythonLibs QUIET) # for Python.h +find_package(Python3 + COMPONENTS + Interpreter # for Python executable + Development # for Python.h + ) CMAKE_DEPENDENT_OPTION(BUILD_PYTHON "Build Python library" ON - "BUILD_LIBRARIES;WITH_PYTHON;PYTHONINTERP_FOUND;PYTHONLIBS_FOUND" OFF) + "BUILD_LIBRARIES;WITH_PYTHON;Python3_Interpreter_FOUND;Python3_Development_FOUND" OFF) # Common library options # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html @@ -206,7 +209,11 @@ MESSAGE_DEP(WITH_NODEJS "Disabled by WITH_NODEJS=OFF") message(STATUS) message(STATUS " Build Python library: ${BUILD_PYTHON}") MESSAGE_DEP(WITH_PYTHON "Disabled by WITH_PYTHON=OFF") -MESSAGE_DEP(PYTHONLIBS_FOUND "Python libraries missing") +MESSAGE_DEP(Python3_Interpreter_FOUND "Python interpreter missing") +MESSAGE_DEP(Python3_Development_FOUND "Python libraries missing") +if(BUILD_PYTHON) + message(STATUS " Version: ${Python3_VERSION}") +endif() if(MSVC) message(STATUS " Using static runtime library: ${WITH_MT}") endif(MSVC) diff --git a/build/cmake/GenerateConfigModule.cmake b/build/cmake/GenerateConfigModule.cmake index 597ffd8f72c..15c094296ff 100644 --- a/build/cmake/GenerateConfigModule.cmake +++ b/build/cmake/GenerateConfigModule.cmake @@ -18,19 +18,16 @@ # include(CMakePackageConfigHelpers) -set(PACKAGE_INCLUDE_INSTALL_DIR "${includedir}/thrift") -set(PACKAGE_CMAKE_INSTALL_DIR "${cmakedir}/thrift") -set(PACKAGE_BIN_INSTALL_DIR "${exec_prefix}") -# In CYGWIN enviroment below commands does not work properly +# In CYGWIN environment below commands does not work properly if (NOT CYGWIN) configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/ThriftConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_DIR}/thrift" PATH_VARS - PACKAGE_INCLUDE_INSTALL_DIR - PACKAGE_CMAKE_INSTALL_DIR - PACKAGE_BIN_INSTALL_DIR + INCLUDE_INSTALL_DIR + CMAKE_INSTALL_DIR + BIN_INSTALL_DIR ) write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake" diff --git a/build/cmake/ThriftConfig.cmake.in b/build/cmake/ThriftConfig.cmake.in index 2f2003bb438..e550fe2575b 100644 --- a/build/cmake/ThriftConfig.cmake.in +++ b/build/cmake/ThriftConfig.cmake.in @@ -21,11 +21,15 @@ set(THRIFT_VERSION @thrift_VERSION@) @PACKAGE_INIT@ -set_and_check(THRIFT_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") -set_and_check(THRIFT_CMAKE_DIR "@PACKAGE_CMAKE_INSTALL_DIR@") -set_and_check(THRIFT_BIN_DIR "@PACKAGE_BIN_INSTALL_DIR@") -if(NOT DEFINED THRIFT_COMPILER) - set(THRIFT_COMPILER "${THRIFT_BIN_DIR}/thrift@CMAKE_EXECUTABLE_SUFFIX@") +set_and_check(THRIFT_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}") + +set_and_check(THRIFT_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@/thrift") + +if(@BUILD_COMPILER@) + set_and_check(THRIFT_BIN_DIR "@PACKAGE_BIN_INSTALL_DIR@") + if(NOT DEFINED THRIFT_COMPILER) + set(THRIFT_COMPILER "${THRIFT_BIN_DIR}/thrift@CMAKE_EXECUTABLE_SUFFIX@") + endif() endif() if (NOT TARGET thrift::thrift) @@ -40,6 +44,20 @@ if(@ZLIB_FOUND@ AND @WITH_ZLIB@) set(THRIFT_LIBRARIES thriftz::thriftz) endif() +if(@Qt5_FOUND@ AND @WITH_QT5@) + if (NOT TARGET thriftqt5::thriftqt5) + include("${THRIFT_CMAKE_DIR}/thriftqt5Targets.cmake") + endif() + set(THRIFT_LIBRARIES thriftqt5::thriftqt5) +endif() + +if(@Libevent_FOUND@ AND @WITH_LIBEVENT@) + if (NOT TARGET thriftnb::thriftnb) + include("${THRIFT_CMAKE_DIR}/thriftnbTargets.cmake") + endif() + set(THRIFT_LIBRARIES thriftnb::thriftnb) +endif() + if ("${THRIFT_LIBRARIES}" STREQUAL "") message(FATAL_ERROR "thrift libraries were not found") endif() diff --git a/build/docker/README.md b/build/docker/README.md index 9c9175ff824..0f2d293dffa 100644 --- a/build/docker/README.md +++ b/build/docker/README.md @@ -20,12 +20,12 @@ logic to determine their behavior: | Variable | Default | Usage | | -------- | ----- | ------- | -| `DISTRO` | `ubuntu-bionic` | Set by various build jobs in `.travis.yml` to run builds in different containers. Not intended to be set externally.| +| `DISTRO` | `ubuntu-focal` | Set by various build jobs in `.travis.yml` to run builds in different containers. Not intended to be set externally.| | `DOCKER_REPO` | `thrift/thrift-build` | The name of the Docker Hub repository to obtain and store docker images. | | `DOCKER_USER` | `` | The Docker Hub account name containing the repository. | | `DOCKER_PASS` | `` | The Docker Hub account password to use when pushing new tags. | -For example, the default docker image that is used in builds if no overrides are specified would be: `thrift/thrift-build:ubuntu-bionic` +For example, the default docker image that is used in builds if no overrides are specified would be: `thrift/thrift-build:ubuntu-focal` ### Forks ### @@ -46,15 +46,15 @@ Docker Hub and push the resulting tags. ## Supported Containers ## -The Travis CI (continuous integration) builds use the Ubuntu Bionic -(18.04 LTS) and Xenial (16.04 LTS) images to maximize language level +The Travis CI (continuous integration) builds use the Ubuntu Noble (24.04 LTS), +Jammy (22.04 LTS) and Focal (20.04 LTS) images to maximize language level coverage. ### Ubuntu ### -* focal (stable, current) -* bionic (previous stable) -* jammy (next stable, WIP) +* focal (stable) +* jammy (stable) +* noble (next stable) ## Unsupported Containers ## @@ -105,16 +105,16 @@ Then, to pull down the current image being used to build (the same way Travis CI does it) - if it is out of date in any way it will build a new one for you: - thrift$ DOCKER_REPO=thrift/thrift-build DISTRO=ubuntu-bionic build/docker/refresh.sh + thrift$ DOCKER_REPO=thrift/thrift-build DISTRO=ubuntu-focal build/docker/refresh.sh To run all unit tests (just like Travis CI does): - thrift$ dockerrun thrift/thrift-build:ubuntu-bionic + thrift$ dockerrun thrift/thrift-build:ubuntu-focal root@8caf56b0ce7b:/thrift/src# build/docker/scripts/autotools.sh To run the cross tests (just like Travis CI does): - thrift$ dockerrun thrift/thrift-build:ubuntu-bionic + thrift$ dockerrun thrift/thrift-build:ubuntu-focal root@8caf56b0ce7b:/thrift/src# build/docker/scripts/cross-test.sh When you are done, you want to clean up occasionally so that docker isn't using lots of extra disk space: @@ -136,7 +136,14 @@ If you do not want to use the same scripts Travis CI does, you can do it manuall Build the image: - thrift$ docker build -t thrift build/docker/ubuntu-bionic +Linux: + + thrift$ docker build --build-arg uid=$(id -u) --build-arg gid=$(id -g) -t thrift build/docker/ubuntu-jammy + +Windows/Mac: + + thrift$ docker build -t thrift build/docker/ubuntu-jammy + Open a command prompt in the image: @@ -144,53 +151,52 @@ Open a command prompt in the image: ## Core Tool Versions per Dockerfile ## -Last updated: October 1, 2017 - -| Tool | ubuntu-xenial | ubuntu-bionic | Notes | -| :-------- | :------------ | :------------ | :---- | -| ant | 1.9.6 | 1.10.3 | | -| autoconf | 2.69 | 2.69 | | -| automake | 1.15 | 1.15.1 | | -| bison | 3.0.4 | 3.0.4 | | -| boost | 1.58.0 | 1.65.1 | | -| cmake | 3.5.1 | 3.10.2 | | -| cppcheck | 1.72 | 1.82 | | -| flex | 2.6.0 | 2.6.4 | | -| libc6 | 2.23 | 2.27 | glibc | -| libevent | 2.0.21 | 2.1.8 | | -| libstdc++ | 5.4.0 | 7.3.0 | | -| make | 4.1 | 4.1 | | -| openssl | 1.0.2g | 1.1.0g | | -| qt5 | 5.5.1 | 5.9.5 | | +Last updated: March 5, 2024 + +| Tool | ubuntu-focal | ubuntu-jammy | ubuntu-noble | Notes | +| :-------- | :------------ | :------------ | :------------ | :---- | +| ant | 1.10.7 | 1.10.12 | | | +| autoconf | 2.69 | 2.71 | | | +| automake | 1.16.1 | 1.16.5 | | | +| bison | 3.5.1 | 3.8.2 | | | +| boost | 1.71.0 | 1.74.0 | | | +| cmake | 3.16.3 | 3.22.1 | | | +| cppcheck | 1.90 | 2.7 | | | +| flex | 2.6.4 | 2.6.4 | | | +| libc6 | 2.31 | 2.35 | | glibc | +| libevent | 2.0.16 | 2.0.16 | | | +| libstdc++ | 10.5.0 | 10.5.0 | | | +| make | 4.2.1 | 4.3 | | | +| openssl | 1.1.1f | 3.0.2 | | | +| qt5 | 5.12.8 | 5.15.3 | | | ## Compiler/Language Versions per Dockerfile ## -| Language | ubuntu-xenial | ubuntu-bionic | Notes | -| :-------- | :------------ | :------------ | :---- | -| as of | Mar 06, 2018 | Jul 1, 2019 | | -| as3 | | 4.6.0 | | -| C++ gcc | 5.4.0 | 7.4.0 | | -| C++ clang | 3.8 | 6.0 | | -| C# (mono) | 4.2.1.0 | 4.6.2.7 | | -| c\_glib | 2.48.2 | 2.56.4 | | -| cl (sbcl) | | 1.5.3 | | -| d | 2.087.0 | 2.087.0 | | -| dart | 2.0.0 | 2.4.0 | | -| delphi | | | Not in CI | -| erlang | OTP-20 | OTP-25 | | -| go | 1.15.10 | 1.16.2 | | -| haxe | 3.2.1 | 3.4.4 | THRIFT-4352: avoid 3.4.2 | -| java | 1.8.0\_191 | 17 | | -| js | Node.js 6.17.1, V8 5.1.281.111, npm 3.10.10 | Node.js 10.18.0, V8 6.8.275.32, npm 6.13.4 | | -| lua | | 5.2.4 | Lua 5.3: see THRIFT-4386 | -| netstd | 7.0 | 7.0 | | -| nodejs | 6.16.0 | 10.16.0 | | -| ocaml | | 4.05.0 | THRIFT-4517: ocaml 4.02.3 on xenial appears broken | -| perl | 5.22.1 | 5.26.1 | | -| php | 7.0.32 | 7.2.19 | | -| python | 2.7.12 | 2.7.15 | | -| python3 | 3.5.2 | 3.6.8 | | -| ruby | 2.3.1p112 | 2.5.1p57 | | -| rust | 1.65.0 | 1.65.0 | | -| smalltalk | | | Not in CI | -| swift | | 5.1.4 | | +| Tool | ubuntu-focal | ubuntu-jammy | ubuntu-noble | Notes | +| :-------- | :------------ | :------------ | :------------ | :---- | +| as of | Mar 06, 2018 | Jul 1, 2019 | | | +| as3 | 4.6.0 | 4.6.0 | | | +| C++ gcc | 9.4.0 | 11.4.0 | | | +| C++ clang | 13.0.0 | 13.0.0 | | | +| c\_glib | 3.2.12 | 3.2.12 | | | +| cl (sbcl) | | 1.5.3 | | | +| d | 2.087.0 | 2.087.0 | | | +| dart | 2.7.2-1 | 2.7.2-1 | | | +| delphi | | | | Not in CI | +| erlang | OTP-25.3.2.9 | OTP-25.3.2.9 | | | +| go | 1.21.7 | 1.21.7 | | | +| haxe | 4.2.1 | 4.2.1 | | | +| java | 17 | 17 | | | +| js | Node.js 16.20.2, npm 8.19.4 | | | Node.js 16.20.2, npm 8.19.4 | +| lua | 5.2.4 | 5.2.4 | | Lua 5.3: see THRIFT-4386 | +| netstd | 9.0 | 9.0 | 9.0 | | +| nodejs | 16.20.2 | 16.20.2 | | | +| ocaml | 4.08.1 | 4.13.1 | | | +| perl | 5.30.0 | 5.34.0 | | | +| php | 7.4.3 | 8.1.2 | 8.3 | | +| python2 | 2.7.18 | | | | +| python3 | 3.8.10 | 3.10.12 | | | +| ruby | 2.7.0p0 | 3.0.2p107 | | | +| rust | 1.83.0 | 1.83.0 | | | +| smalltalk | | | | Not in CI | +| swift | 5.7 | 5.7 | 6.1 | | diff --git a/build/docker/msvc2017/Dockerfile b/build/docker/msvc2017/Dockerfile index d59c19568bc..4502a591f5b 100644 --- a/build/docker/msvc2017/Dockerfile +++ b/build/docker/msvc2017/Dockerfile @@ -13,38 +13,38 @@ # limitations under the License. # -FROM microsoft/dotnet-framework:4.7.1 +FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022 # Restore the default Windows shell for correct batch processing below. SHELL ["cmd", "/S", "/C"] # Install Build Tools excluding workloads and components with known issues. -ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe +ADD --checksum=sha256:ca11782db44225d313c9887b4254dfa57c5b72fef025bf620c81c43dff73c6ed https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ` --installPath C:\BuildTools ` - --all ` - --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 ` - --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 ` - --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 ` - --remove Microsoft.VisualStudio.Component.Windows81SDK ` + --add Microsoft.VisualStudio.Workload.VCTools ` + --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ` || IF "%ERRORLEVEL%"=="3010" EXIT 0 RUN DEL C:\TEMP\vs_buildtools.exe # Install CMake -ADD https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi C:\TEMP\cmake.msi +ADD --checksum=sha256:a10fc2527ec0727a5913acd310cddafba1e5b4ca765ca23cc6a53c55eebb7c1 https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-windows-x86_64.msi C:\TEMP\cmake.msi RUN msiexec.exe /i C:\TEMP\cmake.msi /qn && ` SETX PATH "%PATH%;C:\Program Files\CMake\bin" && ` DEL C:\TEMP\cmake.msi # Install boost (for the thrift runtime library build) -ADD https://boost.teeks99.com/bin/1.69.0/boost_1_69_0-msvc-14.1-64.exe C:\TEMP\boost.exe -RUN C:\TEMP\boost.exe /DIR="C:\Libraries\boost_1_69_0" /SILENT && ` - DEL C:\TEMP\boost.exe +ADD --checksum=sha256:ae6ade62886fd9a6930c95f116a33e940224f0cb7f791b01afd7dd1ceca360fe https://boost.teeks99.com/bin/1.88.0/boost_1_88_0-msvc-14.1-64.exe C:\TEMP\boost.exe +ENV BOOST_ROOT=C:\Libraries\boost_1_88_0 +RUN C:\TEMP\boost.exe /DIR=%BOOST_ROOT% /SILENT && ` + DEL C:\TEMP\boost.exe && ` + SETX BOOST_LIBRARYDIR "%BOOST_ROOT%\lib64-msvc-14.1" && ` + SETX PATH "%BOOST_LIBRARYDIR%;%PATH%" # Install chocolatey RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" ` -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command ` - "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" ` + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" ` && SETX PATH "%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" # Install winflexbison (for the thrift compiler build) @@ -57,44 +57,52 @@ RUN choco install 7zip curl -y COPY appveyor\build-libevent.bat C:\TEMP\build-libevent.bat ENV LIBEVENT_VERSION=2.1.8 ENV WIN3P=C:\TEMP\WIN3P -RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && ` +RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && ` MKDIR C:\TEMP\WIN3P && ` C:\TEMP\build-libevent.bat && ` MKDIR C:\Libraries\libevent-%LIBEVENT_VERSION% && ` MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\include C:\Libraries\libevent-%LIBEVENT_VERSION% && ` MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\lib C:\Libraries\libevent-%LIBEVENT_VERSION% && ` - RMDIR /S /Q C:\TEMP\WIN3P + RMDIR /S /Q C:\TEMP\WIN3P && ` + SETX LIBEVENT_ROOT "C:\Libraries\libevent-%LIBEVENT_VERSION%" # Install zlib COPY appveyor\build-zlib.bat C:\TEMP\build-zlib.bat -ENV ZLIB_VERSION=1.2.11 +ENV ZLIB_VERSION=1.3.1 ENV WIN3P=C:\TEMP\WIN3P -RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && ` +RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && ` MKDIR C:\TEMP\WIN3P && ` C:\TEMP\build-zlib.bat && ` MOVE C:\TEMP\WIN3P\zlib-inst C:\Libraries\zlib-%ZLIB_VERSION% && ` - RMDIR /S /Q C:\TEMP\WIN3P + RMDIR /S /Q C:\TEMP\WIN3P && ` + SETX ZLIB_ROOT "C:\Libraries\zlib-%ZLIB_VERSION%" && ` + SETX PATH "%ZLIB_ROOT%\bin;%PATH%" -# Install OpenSSL 1.1.0 -ADD http://slproweb.com/download/Win64OpenSSL-1_1_0j.exe C:\TEMP\openssl.exe +# Install OpenSSL 3.6.0 +ADD --checksum=sha256:1ae24eb941ff3c11258d0ad4e6d2cba13360cb52a17d8516fb27352b5e3ed6ad https://slproweb.com/download/Win64OpenSSL-3_6_0.exe C:\TEMP\openssl.exe RUN C:\TEMP\openssl.exe /silent && ` - DEL C:\TEMP\openssl.exe + DEL C:\TEMP\openssl.exe && ` + SETX OPENSSL_ROOT "C:\OpenSSL-Win64" && ` + SETX PATH "%OPENSSL_ROOT%\bin;%PATH%" # Install java RUN choco install jdk8 -y # Install python3 RUN choco install python3 -y +RUN pip install setuptools # Install Adobe Flex 4.6 SDK and set FLEX_HOME so it can be found -ADD http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip +ADD --checksum=sha256:622b63f29de44600ff8d4231174a70fcb3085812c0e146a42e91877ca8b46798 http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip RUN CD C:\Adobe\Flex\SDK\4.6 && ` 7z x SDK.zip && ` DEL SDK.zip && ` SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6" +RUN choco install nodejs -y + # Start developer command prompt with any other commands specified. -ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && +ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && # Default to PowerShell if no other command specified. -CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] +CMD powershell.exe -NoLogo -ExecutionPolicy Bypass diff --git a/build/docker/msvc2017/build-compiler.bat b/build/docker/msvc2017/build-compiler.bat index a7ed4798427..a870af84929 100644 --- a/build/docker/msvc2017/build-compiler.bat +++ b/build/docker/msvc2017/build-compiler.bat @@ -26,8 +26,8 @@ cd c:\build :: Generate the out-of-tree build files cmake^ - -DBOOST_ROOT=C:\Libraries\boost_1_69_0^ - -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^ + -DBOOST_ROOT=C:\Libraries\boost_1_89_0^ + -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_89_0\lib64-msvc-14.1^ -DBUILD_LIBRARIES=OFF^ -DCMAKE_BUILD_TYPE=Release^ -DCMAKE_INSTALL_PREFIX=C:\install^ @@ -38,7 +38,7 @@ cmake^ cmake --build . --target thrift-compiler --config Release || EXIT /B :: Test -cmake --build . --target check || EXIT /B +ctest -C Release || EXIT /B :: Install cmake --install . \ No newline at end of file diff --git a/build/docker/msvc2017/build.bat b/build/docker/msvc2017/build.bat index bdf151225b9..a07160b0741 100644 --- a/build/docker/msvc2017/build.bat +++ b/build/docker/msvc2017/build.bat @@ -26,12 +26,13 @@ cd c:\build :: Generate the out-of-tree build files cmake^ - -DBOOST_ROOT=C:\Libraries\boost_1_69_0^ - -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^ - -DFLEX_HOME=C:\Adobe\Flex\SDK\4.6^ - -DLIBEVENT_ROOT=C:\Libraries\libevent-2.1.8^ - -DZLIB_ROOT=C:\Libraries\zlib-1.2.11^ + -DCMAKE_GENERATOR_PLATFORM=x64^ + -DBOOST_ROOT=%BOOST_ROOT%^ + -DFLEX_HOME=%FLEX_HOME%^ + -DLIBEVENT_ROOT=%LIBEVENT_ROOT%^ + -DZLIB_ROOT=%ZLIB_ROOT%^ -DCMAKE_BUILD_TYPE=Release^ + -DBUILD_SHARED_LIBS=OFF^ -DCMAKE_INSTALL_PREFIX=C:\install^ c:\thrift || EXIT /B @@ -39,7 +40,7 @@ cmake^ cmake --build . --config Release || EXIT /B :: Test -cmake --build . --target check || EXIT /B +ctest -C Release || EXIT /B :: Install cmake --install . diff --git a/build/docker/old/Vagrantfile b/build/docker/old/Vagrantfile deleted file mode 100644 index 5eac6e6865f..00000000000 --- a/build/docker/old/Vagrantfile +++ /dev/null @@ -1,59 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Base system bootstrap script -$bootstrap_script = <<__BOOTSTRAP__ -echo "Provisioning defaults" - -sudo apt-get update -y -sudo apt-get upgrade -y - -# Install default packages -sudo apt-get install -y build-essential curl git - -# Install latest Docker version -sudo curl -sSL https://get.docker.io/gpg | sudo apt-key add - -sudo echo "deb http://get.docker.io/ubuntu docker main" > /etc/apt/sources.list.d/docker.list -sudo apt-get update -y -sudo apt-get install -y linux-image-extra-`uname -r` aufs-tools -sudo apt-get install -y lxc-docker - -echo "Finished provisioning defaults" -__BOOTSTRAP__ - -Vagrant.configure("2") do |config| - config.vm.box = "trusty64" - config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" - config.ssh.forward_agent = true - - config.vm.provider :virtualbox do |vbox| - vbox.customize ["modifyvm", :id, "--memory", "1024"] - vbox.customize ["modifyvm", :id, "--cpus", "2"] - end - - # Setup the default bootstrap script for our ubuntu base box image - config.vm.provision "shell", inline: $bootstrap_script - - # Setup the custom docker image from our Ubuntu Dockerfile - config.vm.provision "docker" do |d| - d.build_image "/vagrant/ubuntu", args: "-t thrift" - end - - # Setup the custom docker image from our Centos Dockerfile - #config.vm.provision "docker" do |d| - # d.build_image "/vagrant/centos", args: "-t thrift-centos" - #end - -end diff --git a/build/docker/old/centos-7.3/Dockerfile b/build/docker/old/centos-7.3/Dockerfile deleted file mode 100644 index ba4c54926fd..00000000000 --- a/build/docker/old/centos-7.3/Dockerfile +++ /dev/null @@ -1,196 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Apache Thrift Docker build environment for CentOS -# -# Known missing client libraries: -# - dotnet (will update to 2.0.0 separately) -# - haxe (not in centos) - -FROM centos:7.3.1611 -MAINTAINER Apache Thrift - -RUN yum install -y epel-release - -# General dependencies -RUN yum install -y \ - autoconf \ - bison \ - bison-devel \ - clang \ - clang-analyzer \ - cmake3 \ - curl \ - flex \ - gcc \ - gcc-c++ \ - gdb \ - git \ - libtool \ - m4 \ - make \ - tar \ - unzip \ - valgrind \ - wget && \ - ln -s /usr/bin/cmake3 /usr/bin/cmake && \ - ln -s /usr/bin/cpack3 /usr/bin/cpack && \ - ln -s /usr/bin/ctest3 /usr/bin/ctest - -# C++ dependencies -RUN yum install -y \ - boost-devel-static \ - zlib-devel \ - openssl-devel \ - libevent-devel && \ - cd /usr/lib64 && \ - ln -s libboost_thread-mt.a libboost_thread.a - -# C# Dependencies -RUN yum install -y \ - mono-core \ - mono-devel \ - mono-web-devel \ - mono-extras - -# D Dependencies -RUN yum install -y http://downloads.dlang.org/releases/2.x/2.076.0/dmd-2.076.0-0.fedora.x86_64.rpm xdg-utils -RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - mv libevent-master/deimos/* openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master openssl-master - -# Dart -RUN cd /usr/local && \ - wget -q https://storage.googleapis.com/dart-archive/channels/stable/release/1.24.2/sdk/dartsdk-linux-x64-release.zip && \ - unzip -q dartsdk-linux-x64-release.zip && \ - rm dartsdk-linux-x64-release.zip -ENV PATH /usr/local/dart-sdk/bin:$PATH - -# Erlang Dependencies -RUN curl -sSL http://packages.erlang-solutions.com/rpm/centos/erlang_solutions.repo -o /etc/yum.repos.d/erlang_solutions.repo && \ - yum install -y \ - erlang-kernel \ - erlang-erts \ - erlang-stdlib \ - erlang-eunit \ - erlang-rebar \ - erlang-tools - -# GLibC Dependencies -RUN yum install -y glib2-devel - -# Go Dependencies -RUN curl -sSL https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -C /usr/local/ -xz -ENV PATH /usr/local/go/bin:$PATH - -# Haxe Dependencies -# Not in debian/stretch - -# Java Dependencies -RUN yum install -y \ - ant \ - junit \ - ant-junit \ - java-1.8.0-openjdk-devel - -# Lua Dependencies -# Lua in epel is too old (5.1.4, need 5.2) so we get the latest -RUN yum install -y readline-devel && \ - wget -q http://www.lua.org/ftp/lua-5.3.4.tar.gz && \ - tar xzf lua-5.3.4.tar.gz && \ - cd lua-5.3.4 && \ - sed -i 's/CFLAGS= /CFLAGS= -fPIC /g' src/Makefile && \ - make linux && \ - make install && \ - cd .. && \ - rm -rf lua-5* - -# MinGW Dependencies -RUN yum install -y \ - mingw32-binutils \ - mingw32-crt \ - mingw32-nsis - -# Node.js Dependencies -# Work around epel issue where they removed http-parser that nodejs depends on! -RUN yum -y install https://opensource.enda.eu/packages/http-parser-2.7.1-3.el7.x86_64.rpm -RUN yum install -y \ - nodejs \ - npm - -# Ocaml Dependencies -RUN yum install -y \ - ocaml \ - ocaml-ocamldoc && \ - wget -q https://raw.github.com/ocaml/opam/master/shell/opam_installer.sh -O - | sh -s /usr/local/bin && \ - opam init --yes && \ - opam install --yes oasis && \ - echo '. /root/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true' >> ~/.bashrc - -# Perl Dependencies -RUN yum install -y \ - perl \ - perl-version \ - perl-Bit-Vector \ - perl-Class-Accessor \ - perl-ExtUtils-MakeMaker \ - perl-Test-Simple \ - perl-IO-Socket-SSL \ - perl-Net-SSLeay \ - perl-Crypt-SSLeay - -# PHP Dependencies -RUN yum install -y \ - php \ - php-devel \ - php-pear \ - re2c \ - php-phpunit-PHPUnit \ - bzip2 - -# Python Dependencies -RUN yum install -y \ - python \ - python-devel \ - python-pip \ - python-setuptools \ - python34 \ - python34-devel \ - python34-pip \ - python34-setuptools -RUN pip2 install --upgrade pip -RUN pip2 install --upgrade backports.ssl_match_hostname ipaddress setuptools six tornado tornado-testing twisted virtualenv zope-interface -RUN pip3 install --upgrade pip -RUN pip3 install --upgrade backports.ssl_match_hostname ipaddress setuptools six tornado tornado-testing twisted virtualenv zope-interface - -# Ruby Dependencies -RUN yum install -y \ - ruby \ - ruby-devel \ - rubygems && \ - gem install bundler rake - -# Rust -RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.17.0 -ENV PATH /root/.cargo/bin:$PATH - -# Clean up -RUN rm -rf /tmp/* && \ - yum clean all - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/debian-jessie/Dockerfile b/build/docker/old/debian-jessie/Dockerfile deleted file mode 100644 index 15e02e9c181..00000000000 --- a/build/docker/old/debian-jessie/Dockerfile +++ /dev/null @@ -1,197 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Apache Thrift Docker build environment for Debian -# -# Known missing client libraries: -# - dotnetcore -# - rust - -FROM buildpack-deps:jessie-scm -MAINTAINER Apache Thrift - -ENV DEBIAN_FRONTEND noninteractive - -# Add apt sources -# jessie-backports for cmake and some ruby bits -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" > /etc/apt/sources.list.d/jessie-backports.list - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list && \ - sed -i /etc/apt/sources.list.d/dart_stable.list -e 's/https:/http:/g' - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bison \ - build-essential \ - clang \ - debhelper \ - flex \ - pkg-config && \ - apt-get -t jessie-backports install -y --no-install-recommends cmake - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-7-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-pip \ - python-setuptools \ - python-twisted \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-pip - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-bundler \ - ruby-dev \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get -t jessie-backports install -y ruby-bundler -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php5 \ - php5-dev \ - php5-cli \ - php-pear \ - re2c \ - phpunit \ -`# GlibC dependencies` \ - libglib2.0-dev - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - neko \ - neko-dev \ - libneko0 - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs \ - nodejs-dev \ - nodejs-legacy \ - npm - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# D dependencies` \ - xdg-utils \ -`# Dart dependencies` \ - dart \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev \ -`# MinGW dependencies` \ - mingw32 \ - mingw32-binutils \ -`# mingw32-runtime` \ - nsis \ -`# Clean up` \ - && rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -# Ruby -RUN gem install bundler --no-ri --no-rdoc - -# Python optional dependencies -RUN pip2 install -U ipaddress backports.ssl_match_hostname tornado -RUN pip3 install -U backports.ssl_match_hostname tornado - -# Go -RUN curl -sSL https://storage.googleapis.com/golang/go1.4.3.linux-amd64.tar.gz | tar -C /usr/local/ -xz -ENV PATH /usr/local/go/bin:$PATH - -# Haxe -RUN mkdir -p /usr/lib/haxe && \ - wget -O - https://github.com/HaxeFoundation/haxe/releases/download/3.2.1/haxe-3.2.1-linux64.tar.gz | \ - tar -C /usr/lib/haxe --strip-components=1 -xz && \ - ln -s /usr/lib/haxe/haxe /usr/bin/haxe && \ - ln -s /usr/lib/haxe/haxelib /usr/bin/haxelib && \ - mkdir -p /usr/lib/haxe/lib && \ - chmod -R 777 /usr/lib/haxe/lib && \ - haxelib setup /usr/lib/haxe/lib && \ - haxelib install hxcpp - -# D -RUN curl -sSL http://downloads.dlang.org/releases/2.x/2.070.0/dmd_2.070.0-0_amd64.deb -o /tmp/dmd_2.070.0-0_amd64.deb && \ - dpkg -i /tmp/dmd_2.070.0-0_amd64.deb && \ - rm /tmp/dmd_2.070.0-0_amd64.deb && \ - curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - mv libevent-master/deimos/* openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master openssl-master && \ - echo 'gcc -Wl,--no-as-needed $*' > /usr/local/bin/gcc-dmd && \ - chmod 755 /usr/local/bin/gcc-dmd && \ - echo 'CC=/usr/local/bin/gcc-dmd' >> /etc/dmd.conf - -# Dart -ENV PATH /usr/lib/dart/bin:$PATH - -# OCaml -RUN echo 'deb http://ppa.launchpad.net/avsm/ppa/ubuntu trusty main' > /etc/apt/sources.list.d/avsm-official-ocaml.list && \ - gpg --keyserver keyserver.ubuntu.com --recv 61707B09 && \ - gpg --export --armor 61707B09 | apt-key add - && \ - apt-get update && \ - apt-get install -y ocaml opam && \ - opam init && \ - opam install oasis - -# Force utf8 locale to successfully build Haskell tf-random -ENV LC_ALL C.UTF-8 - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/debian-stretch/Dockerfile b/build/docker/old/debian-stretch/Dockerfile deleted file mode 100644 index f584bba9a96..00000000000 --- a/build/docker/old/debian-stretch/Dockerfile +++ /dev/null @@ -1,225 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Apache Thrift Docker build environment for Debian Stretch -# -# Known issues: -# - d: deimos for libevent and openssl disabled - build errors -# - dotnetcore, because netcore is for 1.0.0-preview and 2.0.0 is out -# - rust: cargo not in debian repo - perhaps not needed? - -FROM buildpack-deps:stretch-scm -MAINTAINER Apache Thrift - -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && apt-get install -y --no-install-recommends apt apt-transport-https curl wget apt-utils - -# D -RUN wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list && \ - apt-get update && apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list && \ - sed -i /etc/apt/sources.list.d/dart_stable.list -e 's/https:/http:/g' - -# dotnet (core) 2.0.0 - project isn't ready for this yet: -# RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ -# echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list - -# node.js (this step runs apt-get update internally) -RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - - -### install general dependencies -RUN apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - ninja-build \ - pkg-config \ - valgrind \ - vim - - -### languages - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# D dependencies` \ - dmd-bin \ - libevent-dev \ - libssl-dev \ - xdg-utils -# libevent deimos disabled - build errors -# RUN mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ -# curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ -# mv libevent-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ -# mv libevent-master/C/* /usr/include/dmd/druntime/import/C/ && \ -# rm -rf libevent-master -# openssl deimos doesn't work with openssl-1.1.0 - disabling it for now: -# RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ -# mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ -# mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ -# rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart -ENV PATH /usr/lib/dart/bin:$PATH - -# project isn't ready for this quite yet: -# RUN apt-get install -y --no-install-recommends \ -# `# dotnet core dependencies` \ -# dotnet-sdk-8.0 \ -# dotnet-runtime-8.0 \ -# aspnetcore-runtime-8.0 \ -# dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -RUN apt-get install -y --no-install-recommends \ -`# golang (go) dependencies` \ - golang-go - -RUN apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - haxe \ - neko \ - neko-dev -RUN haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# same for debian stretch -# lua5.3 does not install alternatives so stick with 5.2 here - -RUN apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs - -RUN apt-get install -y --no-install-recommends \ -`# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php7.0 \ - php7.0-cli \ - php7.0-dev \ - php-pear \ - re2c \ - phpunit - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-backports.ssl-match-hostname \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler -RUN gem install bundler --no-ri --no-rdoc - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - rustc - -# Update anything else left hanging -RUN apt-get dist-upgrade -y - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-artful/Dockerfile b/build/docker/old/ubuntu-artful/Dockerfile deleted file mode 100644 index f94b70086b5..00000000000 --- a/build/docker/old/ubuntu-artful/Dockerfile +++ /dev/null @@ -1,260 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Apache Thrift Docker build environment for Ubuntu Artful -# Using all stock Ubuntu Artful packaging except for: -# - cpp: stock boost 1.62 in artful has a nasty bug so we use stock boost 1.63 -# - d: dmd does not come with Ubuntu -# - dart: does not come with Ubuntu. Pinned to last 1.x release -# - dotnet: does not come with Ubuntu -# - haxe: version 3.4.2 that comes with Ubuntu cores in our CI build -# - go: artful comes with 1.9, we want the latest (supported) -# - nodejs: want v8, artful comes with v6 -# - -FROM buildpack-deps:artful-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ - /etc/apt/sources.list.d/dart_stable.list -ENV DART_VERSION 1.24.3-1 - -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-artful-prod artful main" > \ - /etc/apt/sources.list.d/dotnetdev.list - -# haxe (https://haxe.org/download/linux/) -RUN add-apt-repository ppa:haxe/releases -y - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_8.x artful main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -# boost-1.62 has a terrible bug in boost::test, see https://svn.boost.org/trac10/ticket/12507 -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost1.63-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.4.5 -RUN \ -`# Common Lisp (sbcl) dependencies` \ - curl --version && \ - curl -O -J -L https://kent.dl.sourceforge.net/project/sbcl/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ - tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ - cd sbcl-${SBCL_VERSION}-x86-64-linux && \ - ./install.sh && \ - sbcl --version && \ - rm -rf sbcl* - -ENV D_VERSION 2.080.0 -ENV DMD_DEB dmd_2.080.0-0_amd64.deb -RUN \ -`# D dependencies` \ - wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \ - dpkg --install ${DMD_DEB} && \ - rm -f ${DMD_DEB} && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mv libevent-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master && \ - curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.10 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 b5a64335f1490277b585832d1f6c7f8c6c11206cba5cd3f771dcb87b98ad1a33 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ - echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ - tar -C /usr/local -xzf golang.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ -`# JS dependencies` \ - libxss1 - -RUN apt-get install -y --no-install-recommends \ -`# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ -`# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - cargo \ - rustc - -RUN apt-get install -y --no-install-recommends \ -`# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-disco/Dockerfile b/build/docker/old/ubuntu-disco/Dockerfile deleted file mode 100644 index 39642cf2b00..00000000000 --- a/build/docker/old/ubuntu-disco/Dockerfile +++ /dev/null @@ -1,296 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Apache Thrift Docker build environment for Ubuntu Disco -# with some updated packages. -# - -FROM buildpack-deps:disco-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ - /etc/apt/sources.list.d/dart_stable.list - -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - -# erlang -RUN wget -O- https://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc | apt-key add - && \ - echo "deb https://packages.erlang-solutions.com/ubuntu disco contrib" | tee /etc/apt/sources.list.d/erlang.list - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x disco main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - libasound2 \ - libatk-bridge2.0-0 \ - libgtk-3-0 \ - llvm \ - ninja-build \ - pkg-config \ - unzip \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-6.0/bin:$PATH - -# lib/as3 (ActionScript) -RUN mkdir -p /usr/local/adobe/flex/4.6 && \ - cd /usr/local/adobe/flex/4.6 && \ - wget -q "http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip" && \ - unzip flex_sdk_4.6.zip -ENV FLEX_HOME /usr/local/adobe/flex/4.6 - -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.5.3 -RUN \ - `# Common Lisp (sbcl) dependencies` \ - curl --version && \ - curl -o sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 -J -L https://sourceforge.net/projects/sbcl/files/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2/download?use_mirror=managedway# && \ - tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ - cd sbcl-${SBCL_VERSION}-x86-64-linux && \ - ./install.sh && \ - sbcl --version && \ - cd .. && \ - rm -rf sbcl* - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-0_amd64.deb -RUN \ - `# D dependencies` \ - wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \ - dpkg --install ${DMD_DEB} && \ - rm -f ${DMD_DEB} && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \ - mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-libevent-2.0 && \ - git clone -b 'v2.0.0+1.1.0h' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.1.0h && \ - mv deimos-openssl-1.1.0h/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-openssl-1.1.0h - -ENV DART_VERSION 2.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ - `# Erlang dependencies` \ - erlang && \ - wget https://s3.amazonaws.com/rebar3/rebar3 -O /usr/bin/rebar3 && \ - chmod 755 /usr/bin/rebar3 && \ - rebar3 --version - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.19 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 464b6b66591f6cf055bc5df90a9750bf5fbc9d038722bb84a9d56a2bea974be6 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ - echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ - tar -C /usr/local -xzf golang.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - maven \ - openjdk-11-jdk-headless && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -RUN apt-get install -y --no-install-recommends \ - `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 - -# does not work on disco? -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH - -# Swift on Linux for cross tests -# does not work on disco -# RUN cd / && \ -# wget --quiet https://swift.org/builds/swift-4.2.1-release/ubuntu1804/swift-4.2.1-RELEASE/swift-4.2.1-RELEASE-ubuntu18.04.tar.gz && \ -# tar xf swift-4.2.1-RELEASE-ubuntu18.04.tar.gz --strip-components=1 && \ -# rm swift-4.2.1-RELEASE-ubuntu18.04.tar.gz && \ -# swift --version - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -# cppcheck-1.82 has a nasty cpp parser bug, so we're using something newer -# don't need this on disco, nobody uses it -# RUN apt-get install -y --no-install-recommends \ -# `# Static Code Analysis dependencies` \ -# cppcheck \ -# sloccount && \ -# pip install flake8 && \ -# wget -q "https://launchpad.net/ubuntu/+source/cppcheck/1.83-2/+build/14874703/+files/cppcheck_1.83-2_amd64.deb" && \ -# dpkg -i cppcheck_1.83-2_amd64.deb && \ -# rm cppcheck_1.83-2_amd64.deb - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-trusty/Dockerfile b/build/docker/old/ubuntu-trusty/Dockerfile deleted file mode 100644 index 89f683e4bcf..00000000000 --- a/build/docker/old/ubuntu-trusty/Dockerfile +++ /dev/null @@ -1,235 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Apache Thrift Docker build environment for Ubuntu Trusty -# Using all stock Ubuntu Trusty packaging except for: -# - d: does not come with Ubuntu so we're installing 2.070.0 -# - dart: does not come with Ubuntu so we're installing 1.20.1 -# - dotnetcore, disabled because netcore is for 1.0.0-preview and 2.0.0 is out -# - haxe, disabled because the distro comes with 3.0.0 and it cores while installing -# - node.js, disabled because it is at 0.10.0 in the distro which is too old (need 4+) -# - ocaml, disabled because it fails to install properly -# - -FROM buildpack-deps:trusty-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# D -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EBCF975E5BA24D5E && \ - wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list && \ - wget -qO - https://dlang.org/d-keyring.gpg | apt-key add - - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ - /etc/apt/sources.list.d/dart_stable.list - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# D dependencies` \ - dmd-bin=2.070.2-0 \ - libphobos2-dev=2.070.2-0 \ - dub \ - dfmt \ - dscanner \ - xdg-utils -RUN mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mv libevent-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master -RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart=1.20.1-1 -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.7.6 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 ad5808bf42b014c22dd7646458f631385003049ded0bb6af2efc7f1f79fa29ea -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ - echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ - tar -C /usr/local -xzf golang.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -# disabled because it cores while installing -# RUN apt-get install -y --no-install-recommends \ -# `# Haxe dependencies` \ -# haxe \ -# neko \ -# neko-dev && \ -# haxelib setup /usr/share/haxe/lib && \ -# haxelib install hxcpp 3.2.102 - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-7-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.1 \ - lua5.1-dev - -# disabled because it is too old -# RUN apt-get install -y --no-install-recommends \ -# `# Node.js dependencies` \ -# nodejs \ -# npm - -# disabled because it fails to install properly -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php5 \ - php5-cli \ - php5-dev \ - php-pear \ - re2c && \ - wget https://getcomposer.org/installer -O - -q | php -- --quiet --install-dir=/usr/local/bin/ --filename=composer - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-pip \ - python-setuptools \ - python-six \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-wheel \ - python3-zope.interface && \ - pip install -U ipaddress backports.ssl_match_hostname tornado && \ - pip3 install -U backports.ssl_match_hostname tornado -# installing tornado by pip/pip3 instead of debian package -# if we install the debian package, the build fails in py2 - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler -RUN gem install bundler --no-ri --no-rdoc - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - cargo \ - rustc - -RUN apt-get install -y --no-install-recommends \ -`# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# Install BouncyCastle provider to fix Java builds issues with JDK 7 -# Builds accessing repote repositories fail as seen here: https://github.com/travis-ci/travis-ci/issues/8503 -RUN apt-get install -y --no-install-recommends \ -`# BouncyCastle JCE Provider dependencies` \ - libbcprov-java && \ - ln -s /usr/share/java/bcprov.jar /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/bcprov.jar && \ - awk -F . -v OFS=. 'BEGIN{n=2}/^security\.provider/ {split($3, posAndEquals, "=");$3=n++"="posAndEquals[2];print;next} 1' /etc/java-7-openjdk/security/java.security > /tmp/java.security && \ - echo "security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider" >> /tmp/java.security && \ - mv /tmp/java.security /etc/java-7-openjdk/security/java.security - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-xenial/Dockerfile b/build/docker/old/ubuntu-xenial/Dockerfile deleted file mode 100644 index d9d87ccaea3..00000000000 --- a/build/docker/old/ubuntu-xenial/Dockerfile +++ /dev/null @@ -1,273 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Apache Thrift Docker build environment for Ubuntu Xenial -# Using all stock Ubuntu Xenial packaging except for: -# - d: does not come with Ubuntu so we're installing 2.087.0 for coverage -# - dart: does not come with Ubuntu so we're installing 2.0.0-1 for coverage -# - dotnet: does not come with Ubuntu -# - go: Xenial comes with 1.6, but we need 1.10 or later -# - nodejs: Xenial comes with 4.2.6 which exits LTS April 2018, so we're installing 10.x -# - ocaml: causes stack overflow error, just started March 2018 not sure why -# - -FROM buildpack-deps:xenial-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - software-properties-common \ - wget && \ - - # Dart - curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ - /etc/apt/sources.list.d/dart_stable.list && \ - - # dotnet (core) - curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > \ - /etc/apt/sources.list.d/dotnetdev.list && \ - - # node.js - curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x xenial main" | tee /etc/apt/sources.list.d/nodesource.list && \ - - # ruby 2.4 - apt-add-repository ppa:brightbox/ruby-ng - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -### languages - -# TODO: "apt-get install" without "apt-get update" in the same "RUN" step can cause cache issues if modified later. -# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-0_amd64.deb -RUN \ - `# D dependencies` \ - wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \ - dpkg --install ${DMD_DEB} && \ - rm -f ${DMD_DEB} && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \ - mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-libevent-2.0 && \ - git clone -b 'v1.1.6+1.0.1g' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.0.1g && \ - mv deimos-openssl-1.0.1g/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-openssl-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-openssl-1.0.1g - -ENV DART_VERSION 2.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -# Erlang dependencies -ARG ERLANG_OTP_VERSION=20.3.8.9 -ARG ERLANG_REBAR_VERSION=3.13.2 -RUN apt-get update && apt-get install -y --no-install-recommends automake libncurses5-dev && \ - curl https://raw.githubusercontent.com/kerl/kerl/master/kerl -o /usr/local/bin/kerl && chmod +x /usr/local/bin/kerl && \ - kerl build $ERLANG_OTP_VERSION && kerl install $ERLANG_OTP_VERSION /usr/local/lib/otp/ && . /usr/local/lib/otp/activate && \ - curl https://s3.amazonaws.com/rebar3/rebar3 -o /usr/local/bin/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - curl -ssLo /usr/local/bin/rebar3 https://github.com/erlang/rebar3/releases/download/${ERLANG_REBAR_VERSION}/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - rebar3 --version -ENV PATH /usr/local/lib/otp/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.18.5 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 9e5de37f9c49942c601b191ac5fba404b868bfc21d446d6960acc12283d6e5f2 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ - echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ - tar -C /usr/local -xzf golang.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev \ - libneko0 && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 3.4.64 2>&1 > /dev/null -# note: hxcpp 3.4.185 (latest) no longer ships static libraries, and caused a build failure - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven \ - unzip && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -# disabled: same as ubuntu-bionic jobs -# RUN apt-get install -y --no-install-recommends \ -# `# Lua dependencies` \ -# lua5.2 \ -# lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives so stick with 5.2 here - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 \ - libatk-bridge2.0-0 \ - libgtk-3-0 - -# THRIFT-4517: causes stack overflows; version too old; skip ocaml in xenial -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php7.0 \ - php7.0-cli \ - php7.0-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-backports.ssl-match-hostname \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby2.4 \ - ruby2.4-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -# NOTE: this does not reduce the image size but adds an additional layer. -# # Clean up -# RUN rm -rf /var/cache/apt/* && \ -# rm -rf /var/lib/apt/lists/* && \ -# rm -rf /tmp/* && \ -# rm -rf /var/tmp/* - -ENV DOTNET_CLI_TELEMETRY_OPTOUT 1 -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile deleted file mode 100644 index 350921ae50a..00000000000 --- a/build/docker/ubuntu-bionic/Dockerfile +++ /dev/null @@ -1,299 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Apache Thrift Docker build environment for Ubuntu Bionic -# with some updated packages. -# - -FROM buildpack-deps:bionic-scm -LABEL MAINTAINER='Apache Thrift ' -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update -yq && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends --fix-missing \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ - /etc/apt/sources.list.d/dart_stable.list - -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x bionic main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - libasound2 \ - libatk-bridge2.0-0 \ - libgtk-3-0 \ - llvm \ - ninja-build \ - pkg-config \ - unzip \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-6.0/bin:$PATH - -# lib/as3 (ActionScript) -RUN mkdir -p /usr/local/adobe/flex/4.6 && \ - cd /usr/local/adobe/flex/4.6 && \ - wget -q "http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip" && \ - unzip flex_sdk_4.6.zip -ENV FLEX_HOME /usr/local/adobe/flex/4.6 - -# TODO: "apt-get install" without "apt-get update" in the same "RUN" step can cause cache issues if modified later. -# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.5.3 -RUN \ - `# Common Lisp (sbcl) dependencies` \ - curl --version && \ - curl -o sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 -J -L https://sourceforge.net/projects/sbcl/files/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2/download?use_mirror=managedway# && \ - tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ - cd sbcl-${SBCL_VERSION}-x86-64-linux && \ - ./install.sh && \ - sbcl --version && \ - cd .. && \ - rm -rf sbcl* - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-0_amd64.deb -RUN \ - `# D dependencies` \ - wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \ - dpkg --install ${DMD_DEB} && \ - rm -f ${DMD_DEB} && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \ - mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-libevent-2.0 && \ - git clone -b 'v2.0.0+1.1.0h' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.1.0h && \ - mv deimos-openssl-1.1.0h/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-openssl-1.1.0h - -ENV DART_VERSION 2.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -# Erlang dependencies -ARG ERLANG_OTP_VERSION=23.3.4.11 -ARG ERLANG_REBAR_VERSION=3.18.0 -RUN apt-get update && apt-get install -y --no-install-recommends libncurses5-dev && \ - curl -ssLo /usr/local/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod +x /usr/local/bin/kerl && \ - kerl build $ERLANG_OTP_VERSION && kerl install $ERLANG_OTP_VERSION /usr/local/lib/otp/ && . /usr/local/lib/otp/activate && \ - curl -ssLo /usr/local/bin/rebar3 https://github.com/erlang/rebar3/releases/download/${ERLANG_REBAR_VERSION}/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - rebar3 --version -ENV PATH /usr/local/lib/otp/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.19.5 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 36519702ae2fd573c9869461990ae550c8c0d955cd28d2827a6b159fda81ff95 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ - echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ - tar -C /usr/local -xzf golang.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - maven \ - openjdk-17-jdk-headless && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -RUN apt-get install -y --no-install-recommends \ - `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 - -RUN apt-get install -y --no-install-recommends \ - `# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH - -# Swift on Linux for cross tests -RUN apt-get install -yq \ - libedit-dev \ - libz3-dev \ - libpython-dev \ - libxml2-dev && \ - cd / && \ - wget --quiet https://download.swift.org/swift-5.7-release/ubuntu1804/swift-5.7-RELEASE/swift-5.7-RELEASE-ubuntu18.04.tar.gz && \ - tar xf swift-5.7-RELEASE-ubuntu18.04.tar.gz && \ - mv swift-5.7-RELEASE-ubuntu18.04 /usr/share/swift && \ - rm swift-5.7-RELEASE-ubuntu18.04.tar.gz - -ENV PATH /usr/share/swift/usr/bin:$PATH -RUN swift --version - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -RUN apt-get install -y --no-install-recommends \ - `# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# NOTE: this does not reduce the image size but adds an additional layer. -# # Clean up -# RUN rm -rf /var/cache/apt/* && \ -# rm -rf /var/lib/apt/lists/* && \ -# rm -rf /tmp/* && \ -# rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/ubuntu-focal/Dockerfile b/build/docker/ubuntu-focal/Dockerfile index 416e806469c..18234bf395a 100644 --- a/build/docker/ubuntu-focal/Dockerfile +++ b/build/docker/ubuntu-focal/Dockerfile @@ -32,6 +32,20 @@ RUN apt-get update -yq && \ software-properties-common \ wget +# Create a user +ARG user=build +ARG group=build +ARG uid=1000 +ARG gid=1000 + +RUN apt-get install -y --no-install-recommends sudo && \ + echo "Running with: UID: ${uid}, User: ${user}, GID: ${gid}, Group: ${group}" && \ + if [ -z `cat /etc/group | grep "${group}:"` ] && [ -z `cat /etc/group | grep ":${gid}:"` ]; then addgroup --gid ${gid} ${group}; fi && \ + if [ -z `cat /etc/passwd | grep "${user}:"` ] && [ -z `cat /etc/passwd | grep ":${uid}:"` ]; then adduser --uid ${uid} --gid ${gid} --shell /bin/bash ${user} --disabled-password -q --gecos ""; fi && \ + echo "${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + mkdir -p /home/${user} && \ + chown -R ${user}:${group} /home/${user} + # Dart RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ @@ -39,7 +53,7 @@ RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - & # dotnet (netcore) RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ + wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/20.04/prod.list && \ chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ chown root:root /etc/apt/sources.list.d/microsoft-prod.list @@ -123,6 +137,7 @@ RUN apt-get install -y --no-install-recommends \ dart=$DART_VERSION ENV PATH /usr/lib/dart/bin:$PATH +# Because Ubuntu 20.04 turned EOL in April/May 2025, Microsoft does not support .NET 9 or higher on that platform RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ dotnet-sdk-8.0 \ @@ -145,22 +160,37 @@ RUN apt-get install -y --no-install-recommends \ libglib2.0-dev # golang -ENV GOLANG_VERSION 1.20 +ENV GOLANG_VERSION 1.24.3 ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 5a9ebcc65c1cce56e0d2dc616aff4c4cedcfbda8cc6f0288cc08cda3b18dcbf1 +ENV GOLANG_DOWNLOAD_SHA256 3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ tar -C /usr/local -xzf golang.tar.gz && \ ln -s /usr/local/go/bin/go /usr/local/bin && \ rm golang.tar.gz -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null +# HAXE +ARG HAXE_VERSION=4.2.1 +ARG NEKO_VERSION=2.3.0 +RUN cd $HOME && \ + `# Haxe dependencies` && \ + wget https://github.com/HaxeFoundation/haxe/releases/download/${HAXE_VERSION}/haxe-${HAXE_VERSION}-linux64.tar.gz && \ + tar xvf haxe-${HAXE_VERSION}-linux64.tar.gz && \ + rm haxe-${HAXE_VERSION}-linux64.tar.gz && \ + mv haxe_* /opt/haxe && \ + wget https://github.com/HaxeFoundation/neko/releases/download/v`echo ${NEKO_VERSION} | sed "s/\./-/g"`/neko-${NEKO_VERSION}-linux64.tar.gz && \ + tar xvf neko-${NEKO_VERSION}-linux64.tar.gz && \ + rm neko-${NEKO_VERSION}-linux64.tar.gz && \ + mv neko-* /opt/neko +ENV PATH /opt/haxe:/opt/neko:$PATH +RUN echo "/opt/neko" > /etc/ld.so.conf.d/neko.conf && \ + ldconfig +USER ${user} +RUN mkdir -p $HOME/haxe/lib && \ + haxelib setup --always $HOME/haxe/lib && \ + haxelib install --always hxcpp 2>&1 > /dev/null && \ + haxelib install --always uuid 2>&1 > /dev/null +USER root ENV GRADLE_VERSION="8.4" RUN apt-get install -y --no-install-recommends \ @@ -213,10 +243,13 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ + php7.4 \ + php7.4-cli \ + php7.4-dev \ + php7.4-mbstring \ + php7.4-xml \ + php7.4-curl \ + php7.4-xdebug \ php-pear \ re2c \ composer @@ -228,7 +261,6 @@ RUN apt-get install -y --no-install-recommends \ python3-all-dev \ python3-pip \ python3-setuptools \ - python3-six \ python3-tornado \ python3-twisted \ python3-wheel \ @@ -240,9 +272,11 @@ RUN apt-get install -y --no-install-recommends \ ruby-dev \ ruby-bundler -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH +USER ${user} +RUN `# Rust dependencies` \ + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y +ENV PATH /home/${user}/.cargo/bin:$PATH +USER root # Swift on Linux for cross tests RUN apt-get install -yq \ @@ -281,6 +315,9 @@ RUN apt-get install -y --no-install-recommends \ # rm -rf /var/tmp/* ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src +RUN mkdir -p $THRIFT_ROOT/src && \ + chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src + +USER ${user} diff --git a/build/docker/ubuntu-jammy/Dockerfile b/build/docker/ubuntu-jammy/Dockerfile index a10fea6500a..5e83948316a 100644 --- a/build/docker/ubuntu-jammy/Dockerfile +++ b/build/docker/ubuntu-jammy/Dockerfile @@ -32,17 +32,25 @@ RUN apt-get update -yq && \ software-properties-common \ wget +# Create a user +ARG user=build +ARG group=build +ARG uid=1000 +ARG gid=1000 + +RUN apt-get install -y --no-install-recommends sudo && \ + echo "Running with: UID: ${uid}, User: ${user}, GID: ${gid}, Group: ${group}" && \ + if [ -z `cat /etc/group | grep "${group}:"` ] && [ -z `cat /etc/group | grep ":${gid}:"` ]; then addgroup --gid ${gid} ${group}; fi && \ + if [ -z `cat /etc/passwd | grep "${user}:"` ] && [ -z `cat /etc/passwd | grep ":${uid}:"` ]; then adduser --uid ${uid} --gid ${gid} --shell /bin/bash ${user} --disabled-password -q --gecos ""; fi && \ + echo "${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + mkdir -p /home/${user} && \ + chown -R ${user}:${group} /home/${user} + # Dart RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ /etc/apt/sources.list.d/dart_stable.list -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - # node.js RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ echo "deb https://deb.nodesource.com/node_16.x focal main" | tee /etc/apt/sources.list.d/nodesource.list @@ -84,7 +92,6 @@ RUN apt-get install -y --no-install-recommends \ libboost-all-dev \ libevent-dev \ libssl-dev \ - qt5-default \ qtbase5-dev \ qtbase5-dev-tools @@ -123,15 +130,16 @@ RUN apt-get install -y --no-install-recommends \ dart=$DART_VERSION ENV PATH /usr/lib/dart/bin:$PATH +RUN add-apt-repository ppa:dotnet/backports RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 + dotnet-sdk-10.0 \ + dotnet-runtime-10.0 \ + aspnetcore-runtime-10.0 \ + dotnet-apphost-pack-10.0 # Erlang dependencies -ARG ERLANG_OTP_VERSION=23.3.4.11 +ARG ERLANG_OTP_VERSION=25.3.2.9 ARG ERLANG_REBAR_VERSION=3.18.0 RUN apt-get update && apt-get install -y --no-install-recommends libncurses5-dev && \ curl -ssLo /usr/local/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod +x /usr/local/bin/kerl && \ @@ -145,22 +153,37 @@ RUN apt-get install -y --no-install-recommends \ libglib2.0-dev # golang -ENV GOLANG_VERSION 1.20 +ENV GOLANG_VERSION 1.24.3 ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 5a9ebcc65c1cce56e0d2dc616aff4c4cedcfbda8cc6f0288cc08cda3b18dcbf1 +ENV GOLANG_DOWNLOAD_SHA256 3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ tar -C /usr/local -xzf golang.tar.gz && \ ln -s /usr/local/go/bin/go /usr/local/bin && \ rm golang.tar.gz -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null +# HAXE +ARG HAXE_VERSION=4.2.1 +ARG NEKO_VERSION=2.3.0 +RUN cd $HOME && \ + `# Haxe dependencies` && \ + wget https://github.com/HaxeFoundation/haxe/releases/download/${HAXE_VERSION}/haxe-${HAXE_VERSION}-linux64.tar.gz && \ + tar xvf haxe-${HAXE_VERSION}-linux64.tar.gz && \ + rm haxe-${HAXE_VERSION}-linux64.tar.gz && \ + mv haxe_* /opt/haxe && \ + wget https://github.com/HaxeFoundation/neko/releases/download/v`echo ${NEKO_VERSION} | sed "s/\./-/g"`/neko-${NEKO_VERSION}-linux64.tar.gz && \ + tar xvf neko-${NEKO_VERSION}-linux64.tar.gz && \ + rm neko-${NEKO_VERSION}-linux64.tar.gz && \ + mv neko-* /opt/neko +ENV PATH /opt/haxe:/opt/neko:$PATH +RUN echo "/opt/neko" > /etc/ld.so.conf.d/neko.conf && \ + ldconfig +USER ${user} +RUN mkdir -p $HOME/haxe/lib && \ + haxelib setup --always $HOME/haxe/lib && \ + haxelib install --always hxcpp 2>&1 > /dev/null && \ + haxelib install --always uuid 2>&1 > /dev/null +USER root ENV GRADLE_VERSION="8.4" RUN apt-get install -y --no-install-recommends \ @@ -168,7 +191,7 @@ RUN apt-get install -y --no-install-recommends \ ant \ ant-optional \ maven \ - openjdk-11-jdk-headless && \ + openjdk-17-jdk-headless && \ `# Gradle` \ wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ @@ -178,8 +201,8 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev + lua5.4 \ + liblua5.4-dev # https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 # lua5.3 does not install alternatives! # need to update our luasocket code, lua doesn't have luaL_openlib any more @@ -213,10 +236,13 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ + php8.1 \ + php8.1-cli \ + php8.1-dev \ + php8.1-mbstring \ + php8.1-xml \ + php8.1-curl \ + php8.1-xdebug \ php-pear \ re2c \ composer @@ -228,7 +254,6 @@ RUN apt-get install -y --no-install-recommends \ python3-all-dev \ python3-pip \ python3-setuptools \ - python3-six \ python3-tornado \ python3-twisted \ python3-wheel \ @@ -240,9 +265,11 @@ RUN apt-get install -y --no-install-recommends \ ruby-dev \ ruby-bundler -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH +USER ${user} +RUN `# Rust dependencies` \ + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y +ENV PATH /home/${user}/.cargo/bin:$PATH +USER root # Swift on Linux for cross tests RUN apt-get install -yq \ @@ -281,6 +308,9 @@ RUN apt-get install -y --no-install-recommends \ # rm -rf /var/tmp/* ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src +RUN mkdir -p $THRIFT_ROOT/src && \ + chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src + +USER ${user} diff --git a/build/docker/ubuntu-noble/Dockerfile b/build/docker/ubuntu-noble/Dockerfile new file mode 100644 index 00000000000..86617e009c1 --- /dev/null +++ b/build/docker/ubuntu-noble/Dockerfile @@ -0,0 +1,316 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Apache Thrift Docker build environment for Ubuntu Noble +# with some updated packages. +# + +FROM buildpack-deps:noble-scm +LABEL MAINTAINER="Apache Thrift " +ENV DEBIAN_FRONTEND=noninteractive + +### Add apt repos + +RUN apt-get update -yq && \ + apt-get dist-upgrade -y && \ + apt-get install -y --no-install-recommends --fix-missing \ + apt \ + apt-transport-https \ + apt-utils \ + curl \ + dirmngr \ + software-properties-common \ + wget + +# Create a user +ARG user=build +ARG group=build +ARG uid=1001 +ARG gid=1001 + +RUN apt-get install -y --no-install-recommends sudo && \ + echo "Running with: UID: ${uid}, User: ${user}, GID: ${gid}, Group: ${group}" && \ + if [ -z `cat /etc/group | grep "${group}:"` ] && [ -z `cat /etc/group | grep ":${gid}:"` ]; then addgroup --gid ${gid} ${group}; fi && \ + if [ -z `cat /etc/passwd | grep "${user}:"` ] && [ -z `cat /etc/passwd | grep ":${uid}:"` ]; then adduser --uid ${uid} --gid ${gid} --shell /bin/bash ${user} --disabled-password -q --gecos ""; fi && \ + echo "${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + mkdir -p /home/${user} && \ + chown -R ${user}:${group} /home/${user} + +# Dart +RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ + curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \ + /etc/apt/sources.list.d/dart_stable.list + +# node.js +RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ + echo "deb https://deb.nodesource.com/node_16.x focal main" | tee /etc/apt/sources.list.d/nodesource.list + +### install general dependencies +RUN apt-get update -yq && \ + apt-get install -y --no-install-recommends \ + `# General dependencies` \ + bash-completion \ + bison \ + build-essential \ + clang \ + cmake \ + debhelper \ + flex \ + gdb \ + libatk-bridge2.0-0 \ + libgtk-3-0 \ + llvm \ + ninja-build \ + pkg-config \ + unzip \ + valgrind \ + vim +ENV PATH /usr/lib/llvm-6.0/bin:$PATH + +# lib/as3 (ActionScript) +RUN mkdir -p /usr/local/adobe/flex/4.6 && \ + cd /usr/local/adobe/flex/4.6 && \ + wget -q "http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip" && \ + unzip flex_sdk_4.6.zip +ENV FLEX_HOME /usr/local/adobe/flex/4.6 + +# TODO: "apt-get install" without "apt-get update" in the same "RUN" step can cause cache issues if modified later. +# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run +RUN apt-get install -y --no-install-recommends \ + `# C++ dependencies` \ + libboost-all-dev \ + libevent-dev \ + libssl-dev \ + qtbase5-dev \ + qtbase5-dev-tools + +ENV SBCL_VERSION 1.5.3 +RUN \ + `# Common Lisp (sbcl) dependencies` \ + curl --version && \ + curl -o sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 -J -L https://sourceforge.net/projects/sbcl/files/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2/download?use_mirror=managedway# && \ + tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ + cd sbcl-${SBCL_VERSION}-x86-64-linux && \ + ./install.sh && \ + sbcl --version && \ + cd .. && \ + rm -rf sbcl* + +ENV D_VERSION 2.087.0 +ENV DMD_DEB dmd_2.087.0-0_amd64.deb +RUN \ + `# D dependencies` \ + wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \ + dpkg --install ${DMD_DEB} && \ + rm -f ${DMD_DEB} && \ + mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ + git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \ + mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ + mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \ + rm -rf deimos-libevent-2.0 && \ + git clone -b 'v2.0.0+1.1.0h' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.1.0h && \ + mv deimos-openssl-1.1.0h/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ + mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \ + rm -rf deimos-openssl-1.1.0h + +ENV DART_VERSION 2.7.2-1 +RUN apt-get install -y --no-install-recommends \ + `# Dart dependencies` \ + dart=$DART_VERSION +ENV PATH /usr/lib/dart/bin:$PATH + +RUN add-apt-repository ppa:dotnet/backports +RUN apt-get install -y --no-install-recommends \ + `# dotnet core dependencies` \ + dotnet-sdk-10.0 \ + dotnet-runtime-10.0 \ + aspnetcore-runtime-10.0 \ + dotnet-apphost-pack-10.0 + +# Erlang dependencies +ARG ERLANG_OTP_VERSION=25.3.2.9 +ARG ERLANG_REBAR_VERSION=3.18.0 +RUN apt-get update && apt-get install -y --no-install-recommends libncurses5-dev && \ + curl -ssLo /usr/local/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod +x /usr/local/bin/kerl && \ + kerl build $ERLANG_OTP_VERSION && kerl install $ERLANG_OTP_VERSION /usr/local/lib/otp/ && . /usr/local/lib/otp/activate && \ + curl -ssLo /usr/local/bin/rebar3 https://github.com/erlang/rebar3/releases/download/${ERLANG_REBAR_VERSION}/rebar3 && chmod +x /usr/local/bin/rebar3 && \ + rebar3 --version +ENV PATH /usr/local/lib/otp/bin:$PATH + +RUN apt-get install -y --no-install-recommends \ + `# GlibC dependencies` \ + libglib2.0-dev + +# golang +ENV GOLANG_VERSION 1.24.3 +ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz +ENV GOLANG_DOWNLOAD_SHA256 3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 +RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ + echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ + tar -C /usr/local -xzf golang.tar.gz && \ + ln -s /usr/local/go/bin/go /usr/local/bin && \ + rm golang.tar.gz + +# HAXE +ARG HAXE_VERSION=4.2.1 +ARG NEKO_VERSION=2.3.0 +RUN cd $HOME && \ + `# Haxe dependencies` && \ + wget https://github.com/HaxeFoundation/haxe/releases/download/${HAXE_VERSION}/haxe-${HAXE_VERSION}-linux64.tar.gz && \ + tar xvf haxe-${HAXE_VERSION}-linux64.tar.gz && \ + rm haxe-${HAXE_VERSION}-linux64.tar.gz && \ + mv haxe_* /opt/haxe && \ + wget https://github.com/HaxeFoundation/neko/releases/download/v`echo ${NEKO_VERSION} | sed "s/\./-/g"`/neko-${NEKO_VERSION}-linux64.tar.gz && \ + tar xvf neko-${NEKO_VERSION}-linux64.tar.gz && \ + rm neko-${NEKO_VERSION}-linux64.tar.gz && \ + mv neko-* /opt/neko +ENV PATH /opt/haxe:/opt/neko:$PATH +RUN echo "/opt/neko" > /etc/ld.so.conf.d/neko.conf && \ + ldconfig +USER ${user} +RUN mkdir -p $HOME/haxe/lib && \ + haxelib setup --always $HOME/haxe/lib && \ + haxelib install --always hxcpp 2>&1 > /dev/null && \ + haxelib install --always uuid 2>&1 > /dev/null +USER root + +ENV GRADLE_VERSION="8.4" +RUN apt-get install -y --no-install-recommends \ + `# Java dependencies` \ + ant \ + ant-optional \ + maven \ + openjdk-17-jdk-headless && \ + `# Gradle` \ + wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ + (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ + unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ + mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ + ln -s /usr/local/gradle/bin/gradle /usr/local/bin + +RUN apt-get install -y --no-install-recommends \ + `# Lua dependencies` \ + lua5.4 \ + liblua5.4-dev +# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 +# lua5.3 does not install alternatives! +# need to update our luasocket code, lua doesn't have luaL_openlib any more + +RUN apt-get install -y --no-install-recommends \ + `# Node.js dependencies` \ + nodejs + +# Test dependencies for running puppeteer +RUN apt-get install -y --no-install-recommends \ + `# JS dependencies` \ + libxss1 \ + libxtst6 + +RUN apt-get install -y --no-install-recommends \ + `# OCaml dependencies` \ + ocaml \ + opam && \ + `# disable sandboxing see https://github.com/ocaml/opam/issues/4327` \ + opam init --yes --disable-sandboxing && \ + opam install --yes oasis + +RUN apt-get install -y --no-install-recommends \ + `# Perl dependencies` \ + libbit-vector-perl \ + libclass-accessor-class-perl \ + libcrypt-ssleay-perl \ + libio-socket-ssl-perl \ + libnet-ssleay-perl \ + libtest-exception-perl + +RUN apt-get install -y --no-install-recommends \ + `# Php dependencies` \ + php8.3 \ + php8.3-cli \ + php8.3-dev \ + php8.3-mbstring \ + php8.3-xml \ + php8.3-curl \ + php8.3-xdebug \ + php-pear \ + re2c \ + composer + +RUN apt-get install -y --no-install-recommends \ + `# Python3 dependencies` \ + python3-all \ + python3-all-dbg \ + python3-all-dev \ + python3-pip \ + python3-setuptools \ + python3-tornado \ + python3-twisted \ + python3-wheel \ + python3-zope.interface + +RUN apt-get install -y --no-install-recommends \ + `# Ruby dependencies` \ + ruby \ + ruby-dev \ + ruby-bundler + +USER ${user} +RUN `# Rust dependencies` \ + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y +ENV PATH /home/${user}/.cargo/bin:$PATH +USER root + +# Swift on Linux for cross tests +RUN apt-get install -yq \ + libedit-dev \ + libz3-dev \ + python3-flake8 \ + libxml2-dev && \ + cd / && \ + wget --quiet https://download.swift.org/swift-6.1-release/ubuntu2404/swift-6.1-RELEASE/swift-6.1-RELEASE-ubuntu24.04.tar.gz && \ + tar xf swift-6.1-RELEASE-ubuntu24.04.tar.gz && \ + mv swift-6.1-RELEASE-ubuntu24.04 /usr/share/swift && \ + rm swift-6.1-RELEASE-ubuntu24.04.tar.gz + +ENV PATH /usr/share/swift/usr/bin:$PATH +RUN swift --version + +# Locale(s) for cpp unit tests +RUN apt-get install -y --no-install-recommends \ + `# Locale dependencies` \ + locales && \ + locale-gen en_US.UTF-8 && \ + locale-gen de_DE.UTF-8 && \ + update-locale + +RUN apt-get install -y --no-install-recommends \ + `# Static Code Analysis dependencies` \ + cppcheck \ + sloccount + +#RUN pip install flake8 + +# NOTE: this does not reduce the image size but adds an additional layer. +# # Clean up +# RUN rm -rf /var/cache/apt/* && \ +# rm -rf /var/lib/apt/lists/* && \ +# rm -rf /tmp/* && \ +# rm -rf /var/tmp/* + +ENV THRIFT_ROOT /thrift +RUN mkdir -p $THRIFT_ROOT/src && \ + chown -R ${uid}:${uid} $THRIFT_ROOT/ +COPY Dockerfile $THRIFT_ROOT/ +WORKDIR $THRIFT_ROOT/src + +USER ${user} diff --git a/build/veralign.sh b/build/veralign.sh index 834bf7e03d3..3967d8493d0 100755 --- a/build/veralign.sh +++ b/build/veralign.sh @@ -68,11 +68,16 @@ FILES[lib/java/gradle.properties]=simpleReplace FILES[lib/js/package-lock.json]=jsonReplace FILES[lib/js/package.json]=jsonReplace FILES[lib/js/src/thrift.js]=simpleReplace +FILES[lib/js/package-lock.json]=simpleReplace FILES[lib/lua/Thrift.lua]=simpleReplace -FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace -FILES[lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj]=simpleReplace -FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace +FILES[lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Thrift.Compile.net10.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace FILES[lib/netstd/Thrift/Thrift.csproj]=simpleReplace FILES[lib/ocaml/_oasis]=simpleReplace FILES[lib/perl/lib/Thrift.pm]=simpleReplace @@ -101,6 +106,8 @@ FILES[tutorial/netstd/Client/Client.csproj]=simpleReplace FILES[tutorial/netstd/Interfaces/Interfaces.csproj]=simpleReplace FILES[tutorial/netstd/Server/Server.csproj]=simpleReplace FILES[tutorial/ocaml/_oasis]=simpleReplace +FILES[lib/ts/package-lock.json]=simpleReplace +FILES[package-lock.json]=simpleReplace diff --git a/compiler/cpp/CMakeLists.txt b/compiler/cpp/CMakeLists.txt index b0f123555d8..eeef2035f9d 100644 --- a/compiler/cpp/CMakeLists.txt +++ b/compiler/cpp/CMakeLists.txt @@ -17,7 +17,7 @@ # under the License. # -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.16) project("thrift-compiler" VERSION ${PACKAGE_VERSION}) # version.h now handled via veralign.sh @@ -30,7 +30,7 @@ find_package(BISON REQUIRED) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/) # Create flex and bison files and build the lib parse static library -BISON_TARGET(thrifty ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc) +BISON_TARGET(thrifty ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc COMPILE_FLAGS "--file-prefix-map=${CMAKE_BINARY_DIR}='' --file-prefix-map=${CMAKE_SOURCE_DIR}=''") FLEX_TARGET(thriftl ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/thriftl.ll ${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc) ADD_FLEX_BISON_DEPENDENCY(thriftl thrifty) diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am index bb29d8c47e8..29ef1bd94ca 100644 --- a/compiler/cpp/Makefile.am +++ b/compiler/cpp/Makefile.am @@ -114,6 +114,9 @@ WINDOWS_DIST = \ compiler.vcxproj \ compiler.vcxproj.filters +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ README.md \ diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj index 9fbf903a43a..9cc2ccbb786 100644 --- a/compiler/cpp/compiler.vcxproj +++ b/compiler/cpp/compiler.vcxproj @@ -83,6 +83,8 @@ + + @@ -103,23 +105,27 @@ Application true MultiByte + v143 Application true MultiByte + v143 Application false true MultiByte + v143 Application false true MultiByte + v143 @@ -248,4 +254,4 @@ - + \ No newline at end of file diff --git a/compiler/cpp/src/Makefile.am b/compiler/cpp/src/Makefile.am index 5111fd55038..5b6802a4d84 100644 --- a/compiler/cpp/src/Makefile.am +++ b/compiler/cpp/src/Makefile.am @@ -39,6 +39,9 @@ clean-local: $(RM) thrift/thriftl.cc thrift/thrifty.cc thrift/thrifty.h thrift/thrifty.hh +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ thrift/logging.cc \ thrift/windows/config.h diff --git a/compiler/cpp/src/thrift/generate/go_validator_generator.cc b/compiler/cpp/src/thrift/generate/go_validator_generator.cc index 1f5a3ad6eca..0adff2ee984 100644 --- a/compiler/cpp/src/thrift/generate/go_validator_generator.cc +++ b/compiler/cpp/src/thrift/generate/go_validator_generator.cc @@ -82,19 +82,19 @@ void go_validator_generator::generate_field_validator(std::ostream& out, } if (type->is_enum()) { if (context.tgt[0] == '*') { - out << indent() << "if " << context.tgt.substr(1) << " != nil {" << endl; + out << indent() << "if " << context.tgt.substr(1) << " != nil {" << '\n'; indent_up(); } generate_enum_field_validator(out, context); if (context.tgt[0] == '*') { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } return; } else if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); if (context.tgt[0] == '*') { - out << indent() << "if " << context.tgt.substr(1) << " != nil {" << endl; + out << indent() << "if " << context.tgt.substr(1) << " != nil {" << '\n'; indent_up(); } switch (tbase) { @@ -119,7 +119,7 @@ void go_validator_generator::generate_field_validator(std::ostream& out, } if (context.tgt[0] == '*') { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } return; } else if (type->is_list()) { @@ -146,7 +146,7 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []int64{"; @@ -162,19 +162,19 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } out << ")"; } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if int64(" << context.tgt << ") == src {" << endl; + out << indent() << "if int64(" << context.tgt << ") == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if int64(" << context.tgt << ") != int64("; if (values[0]->is_field_reference()) { @@ -182,18 +182,18 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { out << values[0]->get_enum()->get_value(); } - out << ") {" << endl; + out << ") {" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } else if (key == "vt.not_in") { if (values.size() > 1) { @@ -211,11 +211,11 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } out << ")"; } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if int64(" << context.tgt << ") == src {" << endl; + out << indent() << "if int64(" << context.tgt << ") == src {" << '\n'; } else { out << indent() << "if int64(" << context.tgt << ") == "; out << "int64("; @@ -224,18 +224,18 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { out << values[0]->get_enum()->get_value(); } - out << ") {" << endl; + out << ") {" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } else if (key == "vt.defined_only") { if (values[0]->get_bool()) { @@ -243,14 +243,14 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { continue; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -276,14 +276,14 @@ void go_validator_generator::generate_bool_field_validator(std::ostream& out, } } } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } @@ -308,19 +308,19 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; continue; } else if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []float64{"; @@ -334,19 +334,19 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, out << (*it)->get_double(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if " << context.tgt << " != "; if (values[0]->is_field_reference()) { @@ -354,16 +354,16 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.not_in") { if (values.size() > 1) { std::string src = GenID("_src"); @@ -378,11 +378,11 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, out << (*it)->get_double(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; } else { out << indent() << "if " << context.tgt << " == "; if (values[0]->is_field_reference()) { @@ -390,18 +390,18 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -460,18 +460,18 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []"; @@ -499,19 +499,19 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, out << (*it)->get_int(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if " << context.tgt << " != "; if (values[0]->is_field_reference()) { @@ -531,15 +531,15 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.not_in") { if (values.size() > 1) { std::string src = GenID("_src"); @@ -584,11 +584,11 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, out << (*it)->get_int(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; } else { out << indent() << "if " << context.tgt << " == "; if (values[0]->is_field_reference()) { @@ -608,18 +608,18 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -635,7 +635,7 @@ void go_validator_generator::generate_string_field_validator(std::ostream& out, if (type->is_binary()) { target = GenID("_tgt"); out << indent() << target << " := " - << "string(" << context.tgt << ")" << endl; + << "string(" << context.tgt << ")" << '\n'; } for (auto it = context.rules.begin(); it != context.rules.end(); it++) { const std::vector& values = (*it)->get_values(); @@ -729,14 +729,14 @@ void go_validator_generator::generate_string_field_validator(std::ostream& out, } out << ")"; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } @@ -764,19 +764,19 @@ void go_validator_generator::generate_list_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.elem") { - out << indent() << "for i := 0; i < len(" << context.tgt << ");i++ {" << endl; + out << indent() << "for i := 0; i < len(" << context.tgt << ");i++ {" << '\n'; indent_up(); std::string src = GenID("_elem"); - out << indent() << src << " := " << context.tgt << "[i]" << endl; + out << indent() << src << " := " << context.tgt << "[i]" << '\n'; t_type* elem_type; if (context.type->is_list()) { elem_type = ((t_list*)context.type)->get_elem_type(); @@ -791,7 +791,7 @@ void go_validator_generator::generate_list_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -815,17 +815,17 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.key") { std::string src = GenID("_key"); - out << indent() << "for " << src << " := range " << context.tgt << " {" << endl; + out << indent() << "for " << src << " := range " << context.tgt << " {" << '\n'; indent_up(); generator_context ctx{context.field_symbol + ".key", "", @@ -835,10 +835,10 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.value") { std::string src = GenID("_value"); - out << indent() << "for _, " << src << " := range " << context.tgt << " {" << endl; + out << indent() << "for _, " << src << " := range " << context.tgt << " {" << '\n'; indent_up(); generator_context ctx{context.field_symbol + ".value", "", @@ -848,7 +848,7 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -875,31 +875,31 @@ void go_validator_generator::generate_struct_field_validator(std::ostream& out, } if (generate_valid) { if (last_valid_rule == nullptr) { - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { const std::vector& values = last_valid_rule->get_values(); if (!values[0]->get_bool()) { - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (values[0]->is_field_reference()) { out << indent() << "if !"; out << get_field_reference_name(values[0]->get_field_reference()); - out << "{" << endl; + out << "{" << '\n'; indent_up(); - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc index da25338493c..5cd409118d0 100644 --- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc @@ -39,8 +39,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /* forward declarations */ string initial_caps_to_underscores(string name); string underscores_to_initial_caps(string name); @@ -241,18 +239,18 @@ void t_c_glib_generator::init_generator() { f_types_impl_ << autogen_comment(); /* include inclusion guard */ - f_types_ << "#ifndef " << this->nspace_uc << program_name_uc << "_TYPES_H" << endl << "#define " - << this->nspace_uc << program_name_uc << "_TYPES_H" << endl << endl; + f_types_ << "#ifndef " << this->nspace_uc << program_name_uc << "_TYPES_H" << '\n' << "#define " + << this->nspace_uc << program_name_uc << "_TYPES_H" << '\n' << '\n'; /* include base types */ - f_types_ << "/* base includes */" << endl << "#include " << endl - << "#include " << endl - << "#include " << endl; + f_types_ << "/* base includes */" << '\n' << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n'; /* include other thrift includes */ const vector& includes = program_->get_includes(); if (!includes.empty()) { - f_types_ << "/* other thrift includes */" << endl; + f_types_ << "/* other thrift includes */" << '\n'; for (auto include : includes) { const std::string& include_nspace = include->get_namespace("c_glib"); @@ -260,32 +258,32 @@ void t_c_glib_generator::init_generator() { include_nspace.empty() ? "" : initial_caps_to_underscores(include_nspace) + "_"; f_types_ << "#include \"" << include_nspace_prefix - << initial_caps_to_underscores(include->get_name()) << "_types.h\"" << endl; + << initial_caps_to_underscores(include->get_name()) << "_types.h\"" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; } /* include custom headers */ const vector& c_includes = program_->get_c_includes(); - f_types_ << "/* custom thrift includes */" << endl; + f_types_ << "/* custom thrift includes */" << '\n'; for (const auto & c_include : c_includes) { if (c_include[0] == '<') { - f_types_ << "#include " << c_include << endl; + f_types_ << "#include " << c_include << '\n'; } else { - f_types_ << "#include \"" << c_include << "\"" << endl; + f_types_ << "#include \"" << c_include << "\"" << '\n'; } } - f_types_ << endl; + f_types_ << '\n'; /* include math.h (for "INFINITY") in the implementation file, in case we encounter a struct with a member of type double */ - f_types_impl_ << endl << "#include " << endl; + f_types_impl_ << '\n' << "#include " << '\n'; // include the types file - f_types_impl_ << endl << "#include \"" << this->nspace_lc << program_name_u << "_types.h\"" - << endl << "#include " << endl << endl; + f_types_impl_ << '\n' << "#include \"" << this->nspace_lc << program_name_u << "_types.h\"" + << '\n' << "#include " << '\n' << '\n'; - f_types_ << "/* begin types */" << endl << endl; + f_types_ << "/* begin types */" << '\n' << '\n'; } /** @@ -295,7 +293,7 @@ void t_c_glib_generator::close_generator() { string program_name_uc = to_upper_case(initial_caps_to_underscores(program_name_)); /* end the header inclusion guard */ - f_types_ << "#endif /* " << this->nspace_uc << program_name_uc << "_TYPES_H */" << endl; + f_types_ << "#endif /* " << this->nspace_uc << program_name_uc << "_TYPES_H */" << '\n'; /* close output file */ f_types_.close(); @@ -313,7 +311,7 @@ void t_c_glib_generator::close_generator() { */ void t_c_glib_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " << this->nspace - << ttypedef->get_symbolic() << ";" << endl << endl; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } /** @@ -336,7 +334,7 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); string name_uc = to_upper_case(initial_caps_to_underscores(name)); - f_types_ << indent() << "enum _" << this->nspace << name << " {" << endl; + f_types_ << indent() << "enum _" << this->nspace << name << " {" << '\n'; indent_up(); @@ -349,7 +347,7 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { if (first) { first = false; } else { - f_types_ << "," << endl; + f_types_ << "," << '\n'; } f_types_ << indent() << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name(); @@ -357,19 +355,19 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { } indent_down(); - f_types_ << endl << "};" << endl << "typedef enum _" << this->nspace << name << " " - << this->nspace << name << ";" << endl << endl; + f_types_ << '\n' << "};" << '\n' << "typedef enum _" << this->nspace << name << " " + << this->nspace << name << ";" << '\n' << '\n'; - f_types_ << "/* return the name of the constant */" << endl; - f_types_ << "const char *" << endl; - f_types_ << "toString_" << name << "(int value); " << endl << endl; + f_types_ << "/* return the name of the constant */" << '\n'; + f_types_ << "const char *" << '\n'; + f_types_ << "toString_" << name << "(int value); " << '\n' << '\n'; ; - f_types_impl_ << "/* return the name of the constant */" << endl; - f_types_impl_ << "const char *" << endl; - f_types_impl_ << "toString_" << name << "(int value) " << endl; - f_types_impl_ << "{" << endl; - f_types_impl_ << " static __thread char buf[16] = {0};" << endl; - f_types_impl_ << " switch(value) {" << endl; + f_types_impl_ << "/* return the name of the constant */" << '\n'; + f_types_impl_ << "const char *" << '\n'; + f_types_impl_ << "toString_" << name << "(int value) " << '\n'; + f_types_impl_ << "{" << '\n'; + f_types_impl_ << " static __thread char buf[16] = {0};" << '\n'; + f_types_impl_ << " switch(value) {" << '\n'; std::set done; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); @@ -379,20 +377,20 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { f_types_impl_ << " case " << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name() << ":" << "return \"" << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name() - << "\";" << endl; + << "\";" << '\n'; } } - f_types_impl_ << " default: g_snprintf(buf, 16, \"%d\", value); return buf;" << endl; - f_types_impl_ << " }" << endl; - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << " default: g_snprintf(buf, 16, \"%d\", value); return buf;" << '\n'; + f_types_impl_ << " }" << '\n'; + f_types_impl_ << "}" << '\n' << '\n'; } /** * Generates Thrift constants in C code. */ void t_c_glib_generator::generate_consts(vector consts) { - f_types_ << "/* constants */" << endl; - f_types_impl_ << "/* constants */" << endl; + f_types_ << "/* constants */" << '\n'; + f_types_impl_ << "/* constants */" << '\n'; vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -404,17 +402,17 @@ void t_c_glib_generator::generate_consts(vector consts) { if (is_complex_type(type)) { f_types_ << type_name(type) << indent() << this->nspace_lc << name_lc - << "_constant();" << endl; + << "_constant();" << '\n'; } f_types_ << indent() << "#define " << this->nspace_uc << name_uc << " " - << constant_value(name_lc, type, value) << endl; + << constant_value(name_lc, type, value) << '\n'; generate_const_initializer(name_lc, type, value, true); } - f_types_ << endl; - f_types_impl_ << endl; + f_types_ << '\n'; + f_types_impl_ << '\n'; } /** @@ -439,7 +437,7 @@ void t_c_glib_generator::generate_consts(vector consts) { * // ... additional GObject boilerplate ... */ void t_c_glib_generator::generate_struct(t_struct* tstruct) { - f_types_ << "/* struct " << tstruct->get_name() << " */" << endl; + f_types_ << "/* struct " << tstruct->get_name() << " */" << '\n'; generate_object(tstruct); } @@ -463,21 +461,21 @@ void t_c_glib_generator::generate_service(t_service* tservice) { f_header_ << autogen_comment(); // add an inclusion guard - f_header_ << "#ifndef " << svcname_uc << "_H" << endl << "#define " << svcname_uc << "_H" << endl - << endl; + f_header_ << "#ifndef " << svcname_uc << "_H" << '\n' << "#define " << svcname_uc << "_H" << '\n' + << '\n'; // add standard includes - f_header_ << "#include " << endl << endl; - f_header_ << "#include \"" << this->nspace_lc << program_name_lc << "_types.h\"" << endl; + f_header_ << "#include " << '\n' << '\n'; + f_header_ << "#include \"" << this->nspace_lc << program_name_lc << "_types.h\"" << '\n'; // if we are inheriting from another service, include its header t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_header_ << "#include \"" << this->nspace_lc << to_lower_case(initial_caps_to_underscores(extends_service->get_name())) << ".h\"" - << endl; + << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // create the service implementation string f_service_name = get_out_dir() + filename + ".c"; @@ -487,9 +485,9 @@ void t_c_glib_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment(); // include the headers - f_service_ << "#include " << endl << "#include " << endl - << "#include " << endl << "#include \"" - << filename << ".h\"" << endl << endl; + f_service_ << "#include " << '\n' << "#include " << '\n' + << "#include " << '\n' << "#include \"" + << filename << ".h\"" << '\n' << '\n'; // generate the service-helper classes generate_service_helpers(tservice); @@ -501,7 +499,7 @@ void t_c_glib_generator::generate_service(t_service* tservice) { generate_service_server(tservice); // end the header inclusion guard - f_header_ << "#endif /* " << svcname_uc << "_H */" << endl; + f_header_ << "#endif /* " << svcname_uc << "_H */" << '\n'; // close the files f_service_.close(); @@ -519,27 +517,27 @@ void t_c_glib_generator::generate_xception(t_struct* tstruct) { generate_object(tstruct); - f_types_ << "/* exception */" << endl - << "typedef enum" << endl - << "{" << endl; + f_types_ << "/* exception */" << '\n' + << "typedef enum" << '\n' + << "{" << '\n'; indent_up(); - f_types_ << indent() << this->nspace_uc << name_uc << "_ERROR_CODE" << endl; + f_types_ << indent() << this->nspace_uc << name_uc << "_ERROR_CODE" << '\n'; indent_down(); - f_types_ << "} " << this->nspace << name << "Error;" << endl - << endl + f_types_ << "} " << this->nspace << name << "Error;" << '\n' + << '\n' << "GQuark " << this->nspace_lc << name_lc - << "_error_quark (void);" << endl + << "_error_quark (void);" << '\n' << "#define " << this->nspace_uc << name_uc << "_ERROR (" - << this->nspace_lc << name_lc << "_error_quark())" << endl - << endl - << endl; + << this->nspace_lc << name_lc << "_error_quark())" << '\n' + << '\n' + << '\n'; - f_types_impl_ << "/* define the GError domain for exceptions */" << endl << "#define " + f_types_impl_ << "/* define the GError domain for exceptions */" << '\n' << "#define " << this->nspace_uc << name_uc << "_ERROR_DOMAIN \"" << this->nspace_lc << name_lc - << "_error_quark\"" << endl << "GQuark" << endl << this->nspace_lc << name_lc - << "_error_quark (void)" << endl << "{" << endl + << "_error_quark\"" << '\n' << "GQuark" << '\n' << this->nspace_lc << name_lc + << "_error_quark (void)" << '\n' << "{" << '\n' << " return g_quark_from_static_string (" << this->nspace_uc << name_uc - << "_ERROR_DOMAIN);" << endl << "}" << endl << endl; + << "_ERROR_DOMAIN);" << '\n' << "}" << '\n' << '\n'; } /******************** @@ -983,12 +981,12 @@ string t_c_glib_generator::constant_value_with_storage(string fname, ostringstream render; if (is_numeric(etype)) { render << " " << type_name(etype) << " *" << fname << " = " - << "g_new (" << base_type_name(etype) << ", 1);" << endl + << "g_new (" << base_type_name(etype) << ", 1);" << '\n' << " *" << fname << " = " << constant_value(fname, (t_type*)etype, value) << ";" - << endl; + << '\n'; } else { render << " " << type_name(etype) << " " << fname << " = " - << constant_value(fname, (t_type*)etype, value) << ";" << endl; + << constant_value(fname, (t_type*)etype, value) << ";" << '\n'; } return render.str(); } @@ -1037,22 +1035,22 @@ void t_c_glib_generator::generate_const_initializer(string name, initializers << " constant->" << v_iter->first->get_string() << " = " << constant_value(name + "_constant_" + field_name, field_type, - v_iter->second) << ";" << endl + v_iter->second) << ";" << '\n' << " constant->__isset_" << v_iter->first->get_string() - << " = TRUE;" << endl; + << " = TRUE;" << '\n'; } // implement the initializer f_types_impl_ << maybe_static << this->nspace << type->get_name() << " *" - << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "static " << this->nspace << type->get_name() - << " *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + << " *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "constant = g_object_new (" << this->nspace_uc - << "TYPE_" << type_uc << ", NULL);" << endl + << "TYPE_" << type_uc << ", NULL);" << '\n' << initializers.str(); scope_down(f_types_impl_); @@ -1074,9 +1072,9 @@ void t_c_glib_generator::generate_const_initializer(string name, field_name = tmp(field_name); } - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_list()) { string list_type = "GPtrArray *"; string free_func @@ -1125,33 +1123,33 @@ void t_c_glib_generator::generate_const_initializer(string name, if (list_variable) { initializers << " " << type_name(etype) << " " << fname << " = " << constant_value(fname, (t_type*)etype, (*v_iter)) << ";" - << endl; + << '\n'; appenders << " " << list_appender << "(constant, " << fname << ");" - << endl; + << '\n'; } else { appenders << " " << list_appender << "(constant, " << constant_value(fname, (t_type*)etype, (*v_iter)) << ");" - << endl; + << '\n'; } } - f_types_impl_ << maybe_static << list_type << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << list_type << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "static " << list_type << " constant = NULL;" - << endl - << indent() << "if (constant == NULL)" << endl; + << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); if (!initializers.str().empty()) { f_types_impl_ << initializers.str() - << endl; + << '\n'; } - f_types_impl_ << indent() << "constant = " << list_initializer << endl + f_types_impl_ << indent() << "constant = " << list_initializer << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); @@ -1164,22 +1162,22 @@ void t_c_glib_generator::generate_const_initializer(string name, string ptr = is_numeric(etype) ? "*" : ""; generate_const_initializer(fname, etype, (*v_iter)); initializers << constant_value_with_storage(fname, (t_type*)etype, *v_iter); - appenders << " g_hash_table_insert (constant, " << fname << ", 0);" << endl; + appenders << " g_hash_table_insert (constant, " << fname << ", 0);" << '\n'; } - f_types_impl_ << maybe_static << "GHashTable *" << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << "GHashTable *" << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << initializers.str() << endl - << indent() << "constant = " << generate_new_hash_from_type(etype, nullptr) << endl + f_types_impl_ << initializers.str() << '\n' + << indent() << "constant = " << generate_new_hash_from_type(etype, nullptr) << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); @@ -1197,22 +1195,22 @@ void t_c_glib_generator::generate_const_initializer(string name, initializers << constant_value_with_storage(kname, (t_type*)ktype, v_iter->first); initializers << constant_value_with_storage(vname, (t_type*)vtype, v_iter->second); - appenders << " g_hash_table_insert (constant, " << kname << ", " << vname << ");" << endl; + appenders << " g_hash_table_insert (constant, " << kname << ", " << vname << ");" << '\n'; } - f_types_impl_ << maybe_static << "GHashTable *" << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << "GHashTable *" << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << initializers.str() << endl - << indent() << "constant = " << generate_new_hash_from_type(ktype, vtype) << endl + f_types_impl_ << initializers.str() << '\n' + << indent() << "constant = " << generate_new_hash_from_type(ktype, vtype) << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } } @@ -1303,13 +1301,13 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { string base_service_name_uc = to_upper_case(base_service_name_lc); // Generate the client interface dummy object in the header. - f_header_ << "/* " << service_name_ << " service interface */" << endl << "typedef struct _" + f_header_ << "/* " << service_name_ << " service interface */" << '\n' << "typedef struct _" << this->nspace << service_name_ << "If " << this->nspace << service_name_ << "If; " - << " /* dummy object */" << endl << endl; + << " /* dummy object */" << '\n' << '\n'; // Generate the client interface object in the header. - f_header_ << "struct _" << this->nspace << service_name_ << "IfInterface" << endl << "{" << endl - << " GTypeInterface parent;" << endl << endl; + f_header_ << "struct _" << this->nspace << service_name_ << "IfInterface" << '\n' << "{" << '\n' + << " GTypeInterface parent;" << '\n' << '\n'; /* write out the functions for this interface */ indent_up(); @@ -1330,26 +1328,26 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arglist))) + (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)"; - indent(f_header_) << "gboolean (*" << funname << ") " << params << ";" << endl; + indent(f_header_) << "gboolean (*" << funname << ") " << params << ";" << '\n'; } indent_down(); - f_header_ << "};" << endl << "typedef struct _" << this->nspace << service_name_ << "IfInterface " - << this->nspace << service_name_ << "IfInterface;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "IfInterface " + << this->nspace << service_name_ << "IfInterface;" << '\n' << '\n'; // generate all the interface boilerplate - f_header_ << "GType " << this->nspace_lc << service_name_lc << "_if_get_type (void);" << endl + f_header_ << "GType " << this->nspace_lc << service_name_lc << "_if_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_IF " - << "(" << this->nspace_lc << service_name_lc << "_if_get_type())" << endl << "#define " + << "(" << this->nspace_lc << service_name_lc << "_if_get_type())" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IF(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF, " << this->nspace << service_name_ << "If))" << endl + << service_name_uc << "_IF, " << this->nspace << service_name_ << "If))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_IF(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF))" << endl << "#define " << this->nspace_uc + << service_name_uc << "_IF))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IF_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), " << this->nspace_uc << "TYPE_" << service_name_uc << "_IF, " << this->nspace - << service_name_ << "IfInterface))" << endl << endl; + << service_name_ << "IfInterface))" << '\n' << '\n'; // write out all the interface function prototypes for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1368,50 +1366,50 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { + (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)"; f_header_ << "gboolean " << this->nspace_lc << service_name_lc << "_if_" << funname << " " - << params << ";" << endl; + << params << ";" << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // Generate the client object instance definition in the header. - f_header_ << "/* " << service_name_ << " service client */" << endl << "struct _" << this->nspace - << service_name_ << "Client" << endl << "{" << endl << " " << parent_class_name - << " parent;" << endl; + f_header_ << "/* " << service_name_ << " service client */" << '\n' << "struct _" << this->nspace + << service_name_ << "Client" << '\n' << "{" << '\n' << " " << parent_class_name + << " parent;" << '\n'; if (!extends_service) { // Define "input_protocol" and "output_protocol" properties only // for base services; child service-client classes will inherit // these - f_header_ << endl << " ThriftProtocol *input_protocol;" << endl - << " ThriftProtocol *output_protocol;" << endl; + f_header_ << '\n' << " ThriftProtocol *input_protocol;" << '\n' + << " ThriftProtocol *output_protocol;" << '\n'; } - f_header_ << "};" << endl << "typedef struct _" << this->nspace << service_name_ << "Client " - << this->nspace << service_name_ << "Client;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "Client " + << this->nspace << service_name_ << "Client;" << '\n' << '\n'; // Generate the class definition in the header. - f_header_ << "struct _" << this->nspace << service_name_ << "ClientClass" << endl << "{" << endl - << " " << parent_class_name << "Class parent;" << endl << "};" << endl + f_header_ << "struct _" << this->nspace << service_name_ << "ClientClass" << '\n' << "{" << '\n' + << " " << parent_class_name << "Class parent;" << '\n' << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "ClientClass " << this->nspace - << service_name_ << "ClientClass;" << endl << endl; + << service_name_ << "ClientClass;" << '\n' << '\n'; // Create all the GObject boilerplate - f_header_ << "GType " << this->nspace_lc << service_name_lc << "_client_get_type (void);" << endl + f_header_ << "GType " << this->nspace_lc << service_name_lc << "_client_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_CLIENT " - << "(" << this->nspace_lc << service_name_lc << "_client_get_type())" << endl + << "(" << this->nspace_lc << service_name_lc << "_client_get_type())" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "Client))" << endl + << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "Client))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT_CLASS(c) " << "(G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" << endl << "#define " + << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IS_CLIENT(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_CLIENT))" << endl << "#define " << this->nspace_uc + << service_name_uc << "_CLIENT))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IS_CLIENT_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_CLIENT))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_CLIENT))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" - << endl << endl; + << '\n' << '\n'; /* write out the function prototypes */ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1422,12 +1420,12 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_") + funname, (*f_iter)->get_arglist(), (*f_iter)->get_xceptions()); - indent(f_header_) << function_signature(&service_function) << ";" << endl; + indent(f_header_) << function_signature(&service_function) << ";" << '\n'; t_function send_function(g_type_void, service_name_lc + string("_client_send_") + funname, (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function) << ";" << endl; + indent(f_header_) << function_signature(&send_function) << ";" << '\n'; // implement recv if not a oneway service if (!(*f_iter)->is_oneway()) { @@ -1436,19 +1434,19 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_recv_") + funname, &noargs, (*f_iter)->get_xceptions()); - indent(f_header_) << function_signature(&recv_function) << ";" << endl; + indent(f_header_) << function_signature(&recv_function) << ";" << '\n'; } } /* write out the get/set function prototypes */ f_header_ << "void " + service_name_lc + "_client_set_property (GObject *object, guint " "property_id, const GValue *value, GParamSpec *pspec);" - << endl; + << '\n'; f_header_ << "void " + service_name_lc + "_client_get_property (GObject *object, guint " "property_id, GValue *value, GParamSpec *pspec);" - << endl; + << '\n'; - f_header_ << endl; + f_header_ << '\n'; // end of header code // Generate interface method implementations @@ -1483,76 +1481,76 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { params_without_type += ", "; } - f_service_ << "gboolean" << endl << this->nspace_lc << service_name_lc << "_if_" << funname - << " " << params << endl << "{" << endl << " return " << this->nspace_uc + f_service_ << "gboolean" << '\n' << this->nspace_lc << service_name_lc << "_if_" << funname + << " " << params << '\n' << "{" << '\n' << " return " << this->nspace_uc << service_name_uc << "_IF_GET_INTERFACE (iface)->" << funname << " (" - << params_without_type << "error);" << endl << "}" << endl << endl; + << params_without_type << "error);" << '\n' << "}" << '\n' << '\n'; } // Generate interface boilerplate - f_service_ << "GType" << endl << this->nspace_lc << service_name_lc << "_if_get_type (void)" - << endl << "{" << endl << " static GType type = 0;" << endl << " if (type == 0)" - << endl << " {" << endl << " static const GTypeInfo type_info =" << endl << " {" - << endl << " sizeof (" << this->nspace << service_name_ << "IfInterface)," << endl - << " NULL, /* base_init */" << endl << " NULL, /* base_finalize */" << endl - << " NULL, /* class_init */" << endl << " NULL, /* class_finalize */" - << endl << " NULL, /* class_data */" << endl - << " 0, /* instance_size */" << endl << " 0, /* n_preallocs */" - << endl << " NULL, /* instance_init */" << endl - << " NULL /* value_table */" << endl << " };" << endl - << " type = g_type_register_static (G_TYPE_INTERFACE," << endl + f_service_ << "GType" << '\n' << this->nspace_lc << service_name_lc << "_if_get_type (void)" + << '\n' << "{" << '\n' << " static GType type = 0;" << '\n' << " if (type == 0)" + << '\n' << " {" << '\n' << " static const GTypeInfo type_info =" << '\n' << " {" + << '\n' << " sizeof (" << this->nspace << service_name_ << "IfInterface)," << '\n' + << " NULL, /* base_init */" << '\n' << " NULL, /* base_finalize */" << '\n' + << " NULL, /* class_init */" << '\n' << " NULL, /* class_finalize */" + << '\n' << " NULL, /* class_data */" << '\n' + << " 0, /* instance_size */" << '\n' << " 0, /* n_preallocs */" + << '\n' << " NULL, /* instance_init */" << '\n' + << " NULL /* value_table */" << '\n' << " };" << '\n' + << " type = g_type_register_static (G_TYPE_INTERFACE," << '\n' << " \"" << this->nspace << service_name_ << "If\"," - << endl << " &type_info, 0);" << endl << " }" - << endl << " return type;" << endl << "}" << endl << endl; + << '\n' << " &type_info, 0);" << '\n' << " }" + << '\n' << " return type;" << '\n' << "}" << '\n' << '\n'; // Generate client boilerplate - f_service_ << "static void " << endl << this->nspace_lc << service_name_lc + f_service_ << "static void " << '\n' << this->nspace_lc << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface);" - << endl << endl << "G_DEFINE_TYPE_WITH_CODE (" << this->nspace << service_name_ - << "Client, " << this->nspace_lc << service_name_lc << "_client," << endl - << " " << parent_type_name << ", " << endl + << '\n' << '\n' << "G_DEFINE_TYPE_WITH_CODE (" << this->nspace << service_name_ + << "Client, " << this->nspace_lc << service_name_lc << "_client," << '\n' + << " " << parent_type_name << ", " << '\n' << " G_IMPLEMENT_INTERFACE (" << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF," << endl + << service_name_uc << "_IF," << '\n' << " " << this->nspace_lc - << service_name_lc << "_if_interface_init))" << endl << endl; + << service_name_lc << "_if_interface_init))" << '\n' << '\n'; // Generate property-related code only for base services---child // service-client classes have only properties inherited from their // parent class if (!extends_service) { // Generate client properties - f_service_ << "enum _" << this->nspace << service_name_ << "ClientProperties" << endl << "{" - << endl << " PROP_0," << endl << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_INPUT_PROTOCOL," << endl << " PROP_" << this->nspace_uc - << service_name_uc << "_CLIENT_OUTPUT_PROTOCOL" << endl << "};" << endl << endl; + f_service_ << "enum _" << this->nspace << service_name_ << "ClientProperties" << '\n' << "{" + << '\n' << " PROP_0," << '\n' << " PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_INPUT_PROTOCOL," << '\n' << " PROP_" << this->nspace_uc + << service_name_uc << "_CLIENT_OUTPUT_PROTOCOL" << '\n' << "};" << '\n' << '\n'; // generate property setter - f_service_ << "void" << endl << this->nspace_lc << service_name_lc << "_client_set_property (" + f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_set_property (" << "GObject *object, guint property_id, const GValue *value, " - << "GParamSpec *pspec)" << endl << "{" << endl << " " << this->nspace + << "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace << service_name_ << "Client *client = " << this->nspace_uc << service_name_uc - << "_CLIENT (object);" << endl << endl << " THRIFT_UNUSED_VAR (pspec);" << endl - << endl << " switch (property_id)" << endl << " {" << endl << " case PROP_" - << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << endl - << " client->input_protocol = g_value_get_object (value);" << endl - << " break;" << endl << " case PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL:" << endl - << " client->output_protocol = g_value_get_object (value);" << endl - << " break;" << endl << " }" << endl << "}" << endl << endl; + << "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n' + << '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_" + << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n' + << " client->input_protocol = g_value_get_object (value);" << '\n' + << " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_OUTPUT_PROTOCOL:" << '\n' + << " client->output_protocol = g_value_get_object (value);" << '\n' + << " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n'; // generate property getter - f_service_ << "void" << endl << this->nspace_lc << service_name_lc << "_client_get_property (" + f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_get_property (" << "GObject *object, guint property_id, GValue *value, " - << "GParamSpec *pspec)" << endl << "{" << endl << " " << this->nspace + << "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace << service_name_ << "Client *client = " << this->nspace_uc << service_name_uc - << "_CLIENT (object);" << endl << endl << " THRIFT_UNUSED_VAR (pspec);" << endl - << endl << " switch (property_id)" << endl << " {" << endl << " case PROP_" - << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << endl - << " g_value_set_object (value, client->input_protocol);" << endl - << " break;" << endl << " case PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL:" << endl - << " g_value_set_object (value, client->output_protocol);" << endl - << " break;" << endl << " }" << endl << "}" << endl << endl; + << "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n' + << '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_" + << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n' + << " g_value_set_object (value, client->input_protocol);" << '\n' + << " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_OUTPUT_PROTOCOL:" << '\n' + << " g_value_set_object (value, client->output_protocol);" << '\n' + << " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n'; } // Generate client method implementations @@ -1569,31 +1567,31 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { (*f_iter)->get_arglist()); // Open the send function - indent(f_service_) << function_signature(&send_function) << endl; + indent(f_service_) << function_signature(&send_function) << '\n'; scope_up(f_service_); string reqType = (*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL"; // Serialize the request - f_service_ << indent() << "gint32 cseqid = 0;" << endl << indent() + f_service_ << indent() << "gint32 cseqid = 0;" << '\n' << indent() << "ThriftProtocol * protocol = " << this->nspace_uc << base_service_name_uc - << "_CLIENT (iface)->output_protocol;" << endl << endl << indent() + << "_CLIENT (iface)->output_protocol;" << '\n' << '\n' << indent() << "if (thrift_protocol_write_message_begin (protocol, \"" << name << "\", " - << reqType << ", cseqid, error) < 0)" << endl << indent() << " return FALSE;" - << endl << endl; + << reqType << ", cseqid, error) < 0)" << '\n' << indent() << " return FALSE;" + << '\n' << '\n'; generate_struct_writer(f_service_, arg_struct, "", "", false); - f_service_ << indent() << "if (thrift_protocol_write_message_end (protocol, error) < 0)" << endl - << indent() << " return FALSE;" << endl << indent() - << "if (!thrift_transport_flush (protocol->transport, error))" << endl << indent() - << " return FALSE;" << endl << indent() - << "if (!thrift_transport_write_end (protocol->transport, error))" << endl - << indent() << " return FALSE;" << endl << endl << indent() << "return TRUE;" - << endl; + f_service_ << indent() << "if (thrift_protocol_write_message_end (protocol, error) < 0)" << '\n' + << indent() << " return FALSE;" << '\n' << indent() + << "if (!thrift_transport_flush (protocol->transport, error))" << '\n' << indent() + << " return FALSE;" << '\n' << indent() + << "if (!thrift_transport_write_end (protocol->transport, error))" << '\n' + << indent() << " return FALSE;" << '\n' << '\n' << indent() << "return TRUE;" + << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate recv function only if not an async function if (!(*f_iter)->is_oneway()) { @@ -1603,78 +1601,78 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << function_signature(&recv_function) << endl; + indent(f_service_) << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << "gint32 rseqid;" << endl - << indent() << "gchar * fname = NULL;" << endl - << indent() << "ThriftMessageType mtype;" << endl + f_service_ << indent() << "gint32 rseqid;" << '\n' + << indent() << "gchar * fname = NULL;" << '\n' + << indent() << "ThriftMessageType mtype;" << '\n' << indent() << "ThriftProtocol * protocol = " << this->nspace_uc << base_service_name_uc - << "_CLIENT (iface)->input_protocol;" << endl - << indent() << "ThriftApplicationException *xception;" << endl - << endl + << "_CLIENT (iface)->input_protocol;" << '\n' + << indent() << "ThriftApplicationException *xception;" << '\n' + << '\n' << indent() << "if (thrift_protocol_read_message_begin " - "(protocol, &fname, &mtype, &rseqid, error) < 0) {" << endl; + "(protocol, &fname, &mtype, &rseqid, error) < 0) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl - << indent() << "return FALSE;" << endl; + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << endl - << indent() << "if (mtype == T_EXCEPTION) {" << endl; + f_service_ << indent() << "}" << '\n' + << '\n' + << indent() << "if (mtype == T_EXCEPTION) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' << indent() << "xception = g_object_new " - "(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);" << endl + "(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);" << '\n' << indent() << "thrift_struct_read (THRIFT_STRUCT (xception), " - "protocol, NULL);" << endl + "protocol, NULL);" << '\n' << indent() << "thrift_protocol_read_message_end " - "(protocol, NULL);" << endl + "(protocol, NULL);" << '\n' << indent() << "thrift_transport_read_end " - "(protocol->transport, NULL);" << endl + "(protocol->transport, NULL);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR,xception->type, " - "\"application error: %s\", xception->message);" << endl - << indent() << "g_object_unref (xception);" << endl - << indent() << "return FALSE;" << endl; + "\"application error: %s\", xception->message);" << '\n' + << indent() << "g_object_unref (xception);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "} else if (mtype != T_REPLY) {" << endl; + f_service_ << indent() << "} else if (mtype != T_REPLY) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' << indent() << "thrift_protocol_skip (protocol, T_STRUCT, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_protocol_read_message_end (protocol, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_transport_read_end (" - "protocol->transport, NULL);" << endl + "protocol->transport, NULL);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR, " "THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE, " "\"invalid message type %d, expected T_REPLY\", mtype);" - << endl - << indent() << "return FALSE;" << endl; + << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); f_service_ << indent() << "} else if (strncmp (fname, \"" << name - << "\", " << name.length() << ") != 0) {" << endl; + << "\", " << name.length() << ") != 0) {" << '\n'; indent_up(); f_service_ << indent() << "thrift_protocol_skip (protocol, T_STRUCT, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_protocol_read_message_end (protocol," - "error);" << endl + "error);" << '\n' << indent() << "thrift_transport_read_end (" - "protocol->transport, error);" << endl + "protocol->transport, error);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR, " "THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME, " "\"wrong method name %s, expected " << name - << "\", fname);" << endl - << indent() << "if (fname) g_free (fname);" << endl - << indent() << "return FALSE;" << endl; + << "\", fname);" << '\n' + << indent() << "if (fname) g_free (fname);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << indent() << "if (fname) g_free (fname);" << endl - << endl; + f_service_ << indent() << "}" << '\n' + << indent() << "if (fname) g_free (fname);" << '\n' + << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1699,25 +1697,25 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { } f_service_ << indent() << "if (thrift_protocol_read_message_end (protocol, error) < 0)" - << endl << indent() << " return FALSE;" << endl << endl << indent() - << "if (!thrift_transport_read_end (protocol->transport, error))" << endl - << indent() << " return FALSE;" << endl << endl; + << '\n' << indent() << " return FALSE;" << '\n' << '\n' << indent() + << "if (!thrift_transport_read_end (protocol->transport, error))" << '\n' + << indent() << " return FALSE;" << '\n' << '\n'; // copy over any throw exceptions and return failure for (x_iter = xceptions.begin(); x_iter != xceptions.end(); x_iter++) { - f_service_ << indent() << "if (*" << (*x_iter)->get_name() << " != NULL)" << endl - << indent() << "{" << endl << indent() << " g_set_error (error, " + f_service_ << indent() << "if (*" << (*x_iter)->get_name() << " != NULL)" << '\n' + << indent() << "{" << '\n' << indent() << " g_set_error (error, " << this->nspace_uc << to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name())) << "_ERROR, " << this->nspace_uc << to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name())) - << "_ERROR_CODE, \"" << (*x_iter)->get_type()->get_name() << "\");" << endl - << indent() << " return FALSE;" << endl << indent() << "}" << endl; + << "_ERROR_CODE, \"" << (*x_iter)->get_type()->get_name() << "\");" << '\n' + << indent() << " return FALSE;" << '\n' << indent() << "}" << '\n'; } // Close function - indent(f_service_) << "return TRUE;" << endl; + indent(f_service_) << "return TRUE;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Open function @@ -1725,7 +1723,7 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_") + funname, (*f_iter)->get_arglist(), (*f_iter)->get_xceptions()); - indent(f_service_) << function_signature(&service_function) << endl; + indent(f_service_) << function_signature(&service_function) << '\n'; scope_up(f_service_); // wrap each function @@ -1738,7 +1736,7 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << ", " << (*fld_iter)->get_name(); } - f_service_ << ", error))" << endl << indent() << " return FALSE;" << endl; + f_service_ << ", error))" << '\n' << indent() << " return FALSE;" << '\n'; // if not oneway, implement recv if (!(*f_iter)->is_oneway()) { @@ -1752,20 +1750,20 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { } f_service_ << indent() << "if (!" << this->nspace_lc << service_name_lc << "_client_recv_" - << funname << " (iface, " << ret << "error))" << endl << indent() - << " return FALSE;" << endl; + << funname << " (iface, " << ret << "error))" << '\n' << indent() + << " return FALSE;" << '\n'; } // return TRUE which means all functions were called OK - indent(f_service_) << "return TRUE;" << endl; + indent(f_service_) << "return TRUE;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // create the interface initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_if_interface_init (" - << this->nspace << service_name_ << "IfInterface *iface)" << endl; + << this->nspace << service_name_ << "IfInterface *iface)" << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1773,62 +1771,62 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { string funname = initial_caps_to_underscores((*f_iter)->get_name()); f_service_ << indent() << "iface->" << funname << " = " << this->nspace_lc - << service_name_lc << "_client_" << funname << ";" << endl; + << service_name_lc << "_client_" << funname << ";" << '\n'; } } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (iface);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (iface);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // create the client instance initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_client_init (" - << this->nspace << service_name_ << "Client *client)" << endl; + << this->nspace << service_name_ << "Client *client)" << '\n'; scope_up(f_service_); if (!extends_service) { - f_service_ << indent() << "client->input_protocol = NULL;" << endl - << indent() << "client->output_protocol = NULL;" << endl; + f_service_ << indent() << "client->input_protocol = NULL;" << '\n' + << indent() << "client->output_protocol = NULL;" << '\n'; } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (client);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (client);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // create the client class initializer - f_service_ << "static void" << endl << this->nspace_lc << service_name_lc + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_client_class_init (" << this->nspace << service_name_ << "ClientClass *cls)" - << endl << "{" << endl; + << '\n' << "{" << '\n'; if (!extends_service) { - f_service_ << " GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl - << " GParamSpec *param_spec;" << endl << endl + f_service_ << " GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' + << " GParamSpec *param_spec;" << '\n' << '\n' << " gobject_class->set_property = " << this->nspace_lc << service_name_lc - << "_client_set_property;" << endl + << "_client_set_property;" << '\n' << " gobject_class->get_property = " << this->nspace_lc << service_name_lc - << "_client_get_property;" << endl << endl - << " param_spec = g_param_spec_object (\"input_protocol\"," << endl - << " \"input protocol (construct)\"," << endl - << " \"Set the client input protocol\"," << endl - << " THRIFT_TYPE_PROTOCOL," << endl - << " G_PARAM_READWRITE);" << endl - << " g_object_class_install_property (gobject_class," << endl + << "_client_get_property;" << '\n' << '\n' + << " param_spec = g_param_spec_object (\"input_protocol\"," << '\n' + << " \"input protocol (construct)\"," << '\n' + << " \"Set the client input protocol\"," << '\n' + << " THRIFT_TYPE_PROTOCOL," << '\n' + << " G_PARAM_READWRITE);" << '\n' + << " g_object_class_install_property (gobject_class," << '\n' << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_INPUT_PROTOCOL, param_spec);" << endl << endl - << " param_spec = g_param_spec_object (\"output_protocol\"," << endl - << " \"output protocol (construct)\"," << endl - << " \"Set the client output protocol\"," << endl - << " THRIFT_TYPE_PROTOCOL," << endl - << " G_PARAM_READWRITE);" << endl - << " g_object_class_install_property (gobject_class," << endl + << "_CLIENT_INPUT_PROTOCOL, param_spec);" << '\n' << '\n' + << " param_spec = g_param_spec_object (\"output_protocol\"," << '\n' + << " \"output protocol (construct)\"," << '\n' + << " \"Set the client output protocol\"," << '\n' + << " THRIFT_TYPE_PROTOCOL," << '\n' + << " G_PARAM_READWRITE);" << '\n' + << " g_object_class_install_property (gobject_class," << '\n' << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL, param_spec);" << endl; + << "_CLIENT_OUTPUT_PROTOCOL, param_spec);" << '\n'; } else { - f_service_ << " THRIFT_UNUSED_VAR (cls);" << endl; + f_service_ << " THRIFT_UNUSED_VAR (cls);" << '\n'; } - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } /** @@ -1874,19 +1872,19 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { // Generate the handler class' definition in the header file // Generate the handler instance definition - f_header_ << "/* " << service_name_ << " handler (abstract base class) */" << endl << "struct _" - << class_name << endl << "{" << endl; + f_header_ << "/* " << service_name_ << " handler (abstract base class) */" << '\n' << "struct _" + << class_name << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << " parent;" << endl; + f_header_ << indent() << parent_class_name << " parent;" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << " " << class_name << ";" << endl - << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << " " << class_name << ";" << '\n' + << '\n'; // Generate the handler class definition, including its class members // (methods) - f_header_ << "struct _" << class_name << "Class" << endl << "{" << endl; + f_header_ << "struct _" << class_name << "Class" << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << "Class parent;" << endl << endl; + f_header_ << indent() << parent_class_name << "Class parent;" << '\n' << '\n'; for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { string method_name = initial_caps_to_underscores((*function_iter)->get_name()); @@ -1902,31 +1900,31 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arg_list))) + (has_xceptions ? "" : (", " + xception_list(x_list))) + ", GError **error)"; - indent(f_header_) << "gboolean (*" << method_name << ") " << params << ";" << endl; + indent(f_header_) << "gboolean (*" << method_name << ") " << params << ";" << '\n'; } indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << "Class " << class_name - << "Class;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << "Class " << class_name + << "Class;" << '\n' << '\n'; // Generate the remaining header boilerplate - f_header_ << "GType " << class_name_lc << "_get_type (void);" << endl << "#define " + f_header_ << "GType " << class_name_lc << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_HANDLER " - << "(" << class_name_lc << "_get_type())" << endl << "#define " << class_name_uc + << "(" << class_name_lc << "_get_type())" << '\n' << "#define " << class_name_uc << "(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "))" << endl << "#define " + << service_name_uc << "_HANDLER, " << class_name << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_HANDLER(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER))" << endl << "#define " << class_name_uc + << service_name_uc << "_HANDLER))" << '\n' << "#define " << class_name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "Class))" << endl << "#define " + << service_name_uc << "_HANDLER, " << class_name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_HANDLER_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_HANDLER))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_HANDLER))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_HANDLER_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "Class))" << endl << endl; + << service_name_uc << "_HANDLER, " << class_name << "Class))" << '\n' << '\n'; // Generate the handler class' method definitions for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { @@ -1943,25 +1941,25 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arg_list))) + (has_xceptions ? "" : (", " + xception_list(x_list))) + ", GError **error)"; - f_header_ << "gboolean " << class_name_lc << "_" << method_name << " " << params << ";" << endl; + f_header_ << "gboolean " << class_name_lc << "_" << method_name << " " << params << ";" << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // Generate the handler's implementation in the implementation file // Generate the implementation boilerplate - f_service_ << "static void" << endl << class_name_lc << "_" << service_name_lc + f_service_ << "static void" << '\n' << class_name_lc << "_" << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface);" - << endl << endl; + << '\n' << '\n'; args_indent = string(25, ' '); - f_service_ << "G_DEFINE_TYPE_WITH_CODE (" << class_name << ", " << endl << args_indent - << class_name_lc << "," << endl << args_indent << parent_type_name << "," << endl + f_service_ << "G_DEFINE_TYPE_WITH_CODE (" << class_name << ", " << '\n' << args_indent + << class_name_lc << "," << '\n' << args_indent << parent_type_name << "," << '\n' << args_indent << "G_IMPLEMENT_INTERFACE (" << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF," << endl; + << service_name_uc << "_IF," << '\n'; args_indent += string(23, ' '); f_service_ << args_indent << class_name_lc << "_" << service_name_lc << "_if_interface_init))" - << endl << endl; + << '\n' << '\n'; // Generate the handler method implementations for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { @@ -1982,10 +1980,10 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { x_list, (*function_iter)->is_oneway()); - indent(f_service_) << function_signature(&implementing_function) << endl; + indent(f_service_) << function_signature(&implementing_function) << '\n'; scope_up(f_service_); f_service_ << indent() << "g_return_val_if_fail (" << this->nspace_uc << "IS_" - << service_name_uc << "_HANDLER (iface), FALSE);" << endl << endl << indent() + << service_name_uc << "_HANDLER (iface), FALSE);" << '\n' << '\n' << indent() << "return " << class_name_uc << "_GET_CLASS (iface)" << "->" << method_name << " (iface, "; @@ -1998,42 +1996,42 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { for (field_iter = xceptions.begin(); field_iter != xceptions.end(); ++field_iter) { f_service_ << (*field_iter)->get_name() << ", "; } - f_service_ << "error);" << endl; + f_service_ << "error);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate the handler interface initializer - f_service_ << "static void" << endl << class_name_lc << "_" << service_name_lc + f_service_ << "static void" << '\n' << class_name_lc << "_" << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface)" - << endl; + << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { string method_name = initial_caps_to_underscores((*function_iter)->get_name()); f_service_ << indent() << "iface->" << method_name << " = " << class_name_lc << "_" - << method_name << ";" << endl; + << method_name << ";" << '\n'; } } else { - f_service_ << "THRIFT_UNUSED_VAR (iface);" << endl; + f_service_ << "THRIFT_UNUSED_VAR (iface);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the handler instance initializer - f_service_ << "static void" << endl << class_name_lc << "_init (" << class_name << " *self)" - << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_init (" << class_name << " *self)" + << '\n'; scope_up(f_service_); - f_service_ << indent() << "THRIFT_UNUSED_VAR (self);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (self);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the handler class initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name << "Class *cls)" - << endl; + << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (function_iter = functions.begin(); @@ -2043,14 +2041,14 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { string method_name = initial_caps_to_underscores(function_name); // All methods are pure virtual and must be implemented by subclasses - f_service_ << indent() << "cls->" << method_name << " = NULL;" << endl; + f_service_ << indent() << "cls->" << method_name << " = NULL;" << '\n'; } } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (cls);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (cls);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } /** @@ -2104,84 +2102,84 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // Generate the processor class' definition in the header file // Generate the processor instance definition - f_header_ << "/* " << service_name_ << " processor */" << endl << "struct _" << class_name << endl - << "{" << endl; + f_header_ << "/* " << service_name_ << " processor */" << '\n' << "struct _" << class_name << '\n' + << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << " parent;" << endl << endl << indent() - << "/* protected */" << endl << indent() - << this->nspace + service_name_ + "Handler *handler;" << endl << indent() - << "GHashTable *process_map;" << endl; + f_header_ << indent() << parent_class_name << " parent;" << '\n' << '\n' << indent() + << "/* protected */" << '\n' << indent() + << this->nspace + service_name_ + "Handler *handler;" << '\n' << indent() + << "GHashTable *process_map;" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << " " << class_name << ";" << endl - << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << " " << class_name << ";" << '\n' + << '\n'; // Generate the processor class definition - f_header_ << "struct _" << class_name << "Class" << endl << "{" << endl; + f_header_ << "struct _" << class_name << "Class" << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << "Class parent;" << endl << endl << indent() - << "/* protected */" << endl << indent() - << "gboolean (*dispatch_call) (ThriftDispatchProcessor *processor," << endl; + f_header_ << indent() << parent_class_name << "Class parent;" << '\n' << '\n' << indent() + << "/* protected */" << '\n' << indent() + << "gboolean (*dispatch_call) (ThriftDispatchProcessor *processor," << '\n'; args_indent = indent() + string(27, ' '); - f_header_ << args_indent << "ThriftProtocol *in," << endl << args_indent << "ThriftProtocol *out," - << endl << args_indent << "gchar *fname," << endl << args_indent << "gint32 seqid," - << endl << args_indent << "GError **error);" << endl; + f_header_ << args_indent << "ThriftProtocol *in," << '\n' << args_indent << "ThriftProtocol *out," + << '\n' << args_indent << "gchar *fname," << '\n' << args_indent << "gint32 seqid," + << '\n' << args_indent << "GError **error);" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << "Class " << class_name - << "Class;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << "Class " << class_name + << "Class;" << '\n' << '\n'; // Generate the remaining header boilerplate - f_header_ << "GType " << class_name_lc << "_get_type (void);" << endl << "#define " + f_header_ << "GType " << class_name_lc << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_PROCESSOR " - << "(" << class_name_lc << "_get_type())" << endl << "#define " << class_name_uc + << "(" << class_name_lc << "_get_type())" << '\n' << "#define " << class_name_uc << "(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "))" << endl << "#define " + << service_name_uc << "_PROCESSOR, " << class_name << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_PROCESSOR(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR))" << endl << "#define " << class_name_uc + << service_name_uc << "_PROCESSOR))" << '\n' << "#define " << class_name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << endl << "#define " + << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_PROCESSOR_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_PROCESSOR))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_PROCESSOR))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_PROCESSOR_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << endl << endl; + << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << '\n' << '\n'; // Generate the processor's implementation in the implementation file // Generate the processor's properties enum - f_service_ << "enum _" << class_name << "Properties" << endl << "{" << endl; + f_service_ << "enum _" << class_name << "Properties" << '\n' << "{" << '\n'; indent_up(); - f_service_ << indent() << "PROP_" << class_name_uc << "_0," << endl << indent() << "PROP_" - << class_name_uc << "_HANDLER" << endl; + f_service_ << indent() << "PROP_" << class_name_uc << "_0," << '\n' << indent() << "PROP_" + << class_name_uc << "_HANDLER" << '\n'; indent_down(); - f_service_ << "};" << endl << endl; + f_service_ << "};" << '\n' << '\n'; // Generate the implementation boilerplate args_indent = string(15, ' '); - f_service_ << "G_DEFINE_TYPE (" << class_name << "," << endl << args_indent << class_name_lc - << "," << endl << args_indent << parent_type_name << ")" << endl << endl; + f_service_ << "G_DEFINE_TYPE (" << class_name << "," << '\n' << args_indent << class_name_lc + << "," << '\n' << args_indent << parent_type_name << ")" << '\n' << '\n'; // Generate the processor's processing-function type args_indent = string(process_function_type_name.length() + 23, ' '); f_service_ << "typedef gboolean (* " << process_function_type_name << ") (" - << class_name << " *, " << endl - << args_indent << "gint32," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "GError **);" << endl - << endl; + << class_name << " *, " << '\n' + << args_indent << "gint32," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "GError **);" << '\n' + << '\n'; // Generate the processor's processing-function-definition type - f_service_ << "typedef struct" << endl - << "{" << endl; + f_service_ << "typedef struct" << '\n' + << "{" << '\n'; indent_up(); - f_service_ << indent() << "gchar *name;" << endl - << indent() << process_function_type_name << " function;" << endl; + f_service_ << indent() << "gchar *name;" << '\n' + << indent() << process_function_type_name << " function;" << '\n'; indent_down(); - f_service_ << "} " << process_function_def_type_name << ";" << endl - << endl; + f_service_ << "} " << process_function_def_type_name << ";" << '\n' + << '\n'; // Generate forward declarations of the processor's processing functions so we // can refer to them in the processing-function-definition struct below and @@ -2193,23 +2191,23 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { + initial_caps_to_underscores((*function_iter)->get_name()); args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl + f_service_ << "static gboolean" << '\n' << function_name << " (" - << class_name << " *," << endl - << args_indent << "gint32," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "GError **);" << endl; + << class_name << " *," << '\n' + << args_indent << "gint32," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "GError **);" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the processor's processing-function definitions, if the service // defines any methods if (functions.size() > 0) { f_service_ << indent() << "static " << process_function_def_type_name - << endl + << '\n' << indent() << class_name_lc << "_process_function_defs[" - << functions.size() << "] = {" << endl; + << functions.size() << "] = {" << '\n'; indent_up(); for (function_iter = functions.begin(); function_iter != functions.end(); @@ -2218,17 +2216,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { string process_function_name = class_name_lc + "_process_" + initial_caps_to_underscores(service_function_name); - f_service_ << indent() << "{" << endl; + f_service_ << indent() << "{" << '\n'; indent_up(); - f_service_ << indent() << "\"" << service_function_name << "\"," << endl - << indent() << process_function_name << endl; + f_service_ << indent() << "\"" << service_function_name << "\"," << '\n' + << indent() << process_function_name << '\n'; indent_down(); f_service_ << indent() << "}" - << (function_iter == --functions.end() ? "" : ",") << endl; + << (function_iter == --functions.end() ? "" : ",") << '\n'; } indent_down(); - f_service_ << indent() << "};" << endl - << endl; + f_service_ << indent() << "};" << '\n' + << '\n'; } // Generate the processor's processing functions @@ -2262,76 +2260,76 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { + initial_caps_to_underscores(service_function_name); args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl << function_name << " (" << class_name << " *self," - << endl << args_indent << "gint32 sequence_id," << endl << args_indent - << "ThriftProtocol *input_protocol," << endl << args_indent - << "ThriftProtocol *output_protocol," << endl << args_indent << "GError **error)" - << endl; + f_service_ << "static gboolean" << '\n' << function_name << " (" << class_name << " *self," + << '\n' << args_indent << "gint32 sequence_id," << '\n' << args_indent + << "ThriftProtocol *input_protocol," << '\n' << args_indent + << "ThriftProtocol *output_protocol," << '\n' << args_indent << "GError **error)" + << '\n'; scope_up(f_service_); - f_service_ << indent() << "gboolean result = TRUE;" << endl - << indent() << "ThriftTransport * transport;" << endl - << indent() << "ThriftApplicationException *xception;" << endl - << indent() << args_class_name + " * args =" << endl; + f_service_ << indent() << "gboolean result = TRUE;" << '\n' + << indent() << "ThriftTransport * transport;" << '\n' + << indent() << "ThriftApplicationException *xception;" << '\n' + << indent() << args_class_name + " * args =" << '\n'; indent_up(); - f_service_ << indent() << "g_object_new (" << args_class_type << ", NULL);" << endl << endl; + f_service_ << indent() << "g_object_new (" << args_class_type << ", NULL);" << '\n' << '\n'; indent_down(); if ((*function_iter)->is_oneway()) { - f_service_ << indent() << "THRIFT_UNUSED_VAR (sequence_id);" << endl << indent() - << "THRIFT_UNUSED_VAR (output_protocol);" << endl << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (sequence_id);" << '\n' << indent() + << "THRIFT_UNUSED_VAR (output_protocol);" << '\n' << '\n'; } f_service_ << indent() << "g_object_get (input_protocol, \"transport\", " - << "&transport, NULL);" << endl << endl; + << "&transport, NULL);" << '\n' << '\n'; // Read the method's arguments from the caller f_service_ << indent() << "if ((thrift_struct_read (THRIFT_STRUCT (args), " - << "input_protocol, error) != -1) &&" << endl << indent() + << "input_protocol, error) != -1) &&" << '\n' << indent() << " (thrift_protocol_read_message_end (input_protocol, " - << "error) != -1) &&" << endl << indent() - << " (thrift_transport_read_end (transport, error) != FALSE))" << endl; + << "error) != -1) &&" << '\n' << indent() + << " (thrift_transport_read_end (transport, error) != FALSE))" << '\n'; scope_up(f_service_); for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { f_service_ << indent() << property_type_name((*arg_iter)->get_type()) << " " - << (*arg_iter)->get_name() << ";" << endl; + << (*arg_iter)->get_name() << ";" << '\n'; } for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << indent() << type_name((*xception_iter)->get_type()) << " " - << initial_caps_to_underscores((*xception_iter)->get_name()) << " = NULL;" << endl; + << initial_caps_to_underscores((*xception_iter)->get_name()) << " = NULL;" << '\n'; } if (has_return_value) { - f_service_ << indent() << property_type_name(return_type) << " return_value;" << endl; + f_service_ << indent() << property_type_name(return_type) << " return_value;" << '\n'; } if (!(*function_iter)->is_oneway()) { - f_service_ << indent() << result_class_name << " * result_struct;" << endl; + f_service_ << indent() << result_class_name << " * result_struct;" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; if (args.size() > 0) { - f_service_ << indent() << "g_object_get (args," << endl; + f_service_ << indent() << "g_object_get (args," << '\n'; args_indent = indent() + string(14, ' '); for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { string arg_name = (*arg_iter)->get_name(); - f_service_ << args_indent << "\"" << arg_name << "\", &" << arg_name << "," << endl; + f_service_ << args_indent << "\"" << arg_name << "\", &" << arg_name << "," << '\n'; } - f_service_ << args_indent << "NULL);" << endl << endl; + f_service_ << args_indent << "NULL);" << '\n' << '\n'; } if (!(*function_iter)->is_oneway()) { - f_service_ << indent() << "g_object_unref (transport);" << endl << indent() + f_service_ << indent() << "g_object_unref (transport);" << '\n' << indent() << "g_object_get (output_protocol, \"transport\", " - << "&transport, NULL);" << endl << endl << indent() - << "result_struct = g_object_new (" << result_class_type << ", NULL);" << endl; + << "&transport, NULL);" << '\n' << '\n' << indent() + << "result_struct = g_object_new (" << result_class_type << ", NULL);" << '\n'; if (has_return_value) { f_service_ << indent() << "g_object_get (result_struct, " - "\"success\", &return_value, NULL);" << endl; + "\"success\", &return_value, NULL);" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; } // Pass the arguments to the corresponding method in the handler f_service_ << indent() << "if (" << handler_function_name << " (" << this->nspace_uc - << service_name_uc << "_IF (self->handler)," << endl; + << service_name_uc << "_IF (self->handler)," << '\n'; args_indent = indent() + string(handler_function_name.length() + 6, ' '); if (has_return_value) { string return_type_name = type_name(return_type); @@ -2351,16 +2349,16 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { f_service_ << "(" << return_type_name << ")"; } - f_service_ << "&return_value," << endl; + f_service_ << "&return_value," << '\n'; } for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { - f_service_ << args_indent << (*arg_iter)->get_name() << "," << endl; + f_service_ << args_indent << (*arg_iter)->get_name() << "," << '\n'; } for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << args_indent << "&" << initial_caps_to_underscores((*xception_iter)->get_name()) - << "," << endl; + << "," << '\n'; } - f_service_ << args_indent << "error) == TRUE)" << endl; + f_service_ << args_indent << "error) == TRUE)" << '\n'; scope_up(f_service_); // The handler reported success; return the result, if any, to the caller @@ -2373,24 +2371,24 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { << "(" << type_name(return_type) << ")"; } f_service_ << "return_value, " - << "NULL);" << endl; - f_service_ << endl; + << "NULL);" << '\n'; + f_service_ << '\n'; } - f_service_ << indent() << "result =" << endl; + f_service_ << indent() << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_REPLY," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_REPLY," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); } scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; scope_up(f_service_); // The handler reported failure; check to see if an application-defined @@ -2399,28 +2397,28 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { if (xceptions.size() > 0) { for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << "if (" << initial_caps_to_underscores((*xception_iter)->get_name()) - << " != NULL)" << endl; + << " != NULL)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "g_object_set (result_struct," << endl; + f_service_ << indent() << "g_object_set (result_struct," << '\n'; args_indent = indent() + string(14, ' '); f_service_ << args_indent << "\"" << (*xception_iter)->get_name() << "\", " - << (*xception_iter)->get_name() << "," << endl << args_indent << "NULL);" << endl - << endl; - f_service_ << indent() << "g_object_unref ("<< (*xception_iter)->get_name() <<");"<< endl; - f_service_ << indent() << "result =" << endl; + << (*xception_iter)->get_name() << "," << '\n' << args_indent << "NULL);" << '\n' + << '\n'; + f_service_ << indent() << "g_object_unref ("<< (*xception_iter)->get_name() <<");"<< '\n'; + f_service_ << indent() << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_REPLY," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_REPLY," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; } scope_up(f_service_); @@ -2430,41 +2428,41 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // If the handler reported failure but raised no application-defined // exception, return a Thrift application exception with the information // returned via GLib's own error-reporting mechanism - f_service_ << "if (*error == NULL)" << endl; + f_service_ << "if (*error == NULL)" << '\n'; indent_up(); f_service_ << indent() << "g_warning (\"" << service_name_ << "." - << (*function_iter)->get_name() << " implementation returned FALSE \"" << endl - << indent() << string(11, ' ') << "\"but did not set an error\");" << endl << endl; + << (*function_iter)->get_name() << " implementation returned FALSE \"" << '\n' + << indent() << string(11, ' ') << "\"but did not set an error\");" << '\n' << '\n'; indent_down(); - f_service_ << indent() << "xception =" << endl; + f_service_ << indent() << "xception =" << '\n'; indent_up(); - f_service_ << indent() << "g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION," << endl; + f_service_ << indent() << "g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION," << '\n'; args_indent = indent() + string(14, ' '); - f_service_ << args_indent << "\"type\", *error != NULL ? (*error)->code :" << endl + f_service_ << args_indent << "\"type\", *error != NULL ? (*error)->code :" << '\n' << args_indent << string(11, ' ') << "THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN," - << endl << args_indent << "\"message\", *error != NULL ? (*error)->message : NULL," - << endl << args_indent << "NULL);" << endl; + << '\n' << args_indent << "\"message\", *error != NULL ? (*error)->message : NULL," + << '\n' << args_indent << "NULL);" << '\n'; indent_down(); - f_service_ << indent() << "g_clear_error (error);" << endl << endl << indent() - << "result =" << endl; + f_service_ << indent() << "g_clear_error (error);" << '\n' << '\n' << indent() + << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_EXCEPTION," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (xception)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_EXCEPTION," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (xception)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); - f_service_ << endl << indent() << "g_object_unref (xception);" << endl; + f_service_ << '\n' << indent() << "g_object_unref (xception);" << '\n'; if (xceptions.size() > 0) { scope_down(f_service_); } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Dellocate or unref retrieved argument values as necessary for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { @@ -2475,17 +2473,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { t_base_type* base_type = ((t_base_type*)arg_type); if (base_type->get_base() == t_base_type::TYPE_STRING) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { - f_service_ << indent() << "g_byte_array_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_byte_array_unref (" << arg_name << ");" << '\n'; } else { - f_service_ << indent() << "g_free (" << arg_name << ");" << endl; + f_service_ << indent() << "g_free (" << arg_name << ");" << '\n'; } indent_down(); } } else if (arg_type->is_container()) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); if (arg_type->is_list()) { @@ -2497,16 +2495,16 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { } else { f_service_ << "g_ptr_array_unref"; } - f_service_ << " (" << arg_name << ");" << endl; + f_service_ << " (" << arg_name << ");" << '\n'; } else if (arg_type->is_map() || arg_type->is_set()) { - f_service_ << indent() << "g_hash_table_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_hash_table_unref (" << arg_name << ");" << '\n'; } indent_down(); } else if (arg_type->is_struct()) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_object_unref (" << arg_name << ");" << '\n'; indent_down(); } } @@ -2518,17 +2516,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { if (return_type->is_base_type()) { t_base_type* base_type = ((t_base_type*)return_type); if (base_type->get_base() == t_base_type::TYPE_STRING) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { - f_service_ << indent() << "g_byte_array_unref (return_value);" << endl; + f_service_ << indent() << "g_byte_array_unref (return_value);" << '\n'; } else { - f_service_ << indent() << "g_free (return_value);" << endl; + f_service_ << indent() << "g_free (return_value);" << '\n'; } indent_down(); } } else if (return_type->is_container()) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); if (return_type->is_list()) { @@ -2540,81 +2538,81 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { } else { f_service_ << "g_ptr_array_unref"; } - f_service_ << " (return_value);" << endl; + f_service_ << " (return_value);" << '\n'; } else if (return_type->is_map() || return_type->is_set()) { - f_service_ << indent() << "g_hash_table_unref (return_value);" << endl; + f_service_ << indent() << "g_hash_table_unref (return_value);" << '\n'; } indent_down(); } else if (return_type->is_struct()) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (return_value);" << endl; + f_service_ << indent() << "g_object_unref (return_value);" << '\n'; indent_down(); } } - f_service_ << indent() << "g_object_unref (result_struct);" << endl << endl << indent() - << "if (result == TRUE)" << endl; + f_service_ << indent() << "g_object_unref (result_struct);" << '\n' << '\n' << indent() + << "if (result == TRUE)" << '\n'; indent_up(); - f_service_ << indent() << "result =" << endl; + f_service_ << indent() << "result =" << '\n'; indent_up(); f_service_ << indent() << "((thrift_protocol_write_message_end " - << "(output_protocol, error) != -1) &&" << endl << indent() + << "(output_protocol, error) != -1) &&" << '\n' << indent() << " (thrift_transport_write_end (transport, error) " - << "!= FALSE) &&" << endl << indent() + << "!= FALSE) &&" << '\n' << indent() << " (thrift_transport_flush (transport, error) " - << "!= FALSE));" << endl; + << "!= FALSE));" << '\n'; indent_down(); indent_down(); } scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; indent_up(); - f_service_ << indent() << "result = FALSE;" << endl; + f_service_ << indent() << "result = FALSE;" << '\n'; indent_down(); - f_service_ << endl << indent() << "g_object_unref (transport);" << endl << indent() - << "g_object_unref (args);" << endl << endl << indent() << "return result;" << endl; + f_service_ << '\n' << indent() << "g_object_unref (transport);" << '\n' << indent() + << "g_object_unref (args);" << '\n' << '\n' << indent() << "return result;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate the processor's dispatch_call implementation function_name = class_name_lc + "_dispatch_call"; args_indent = indent() + string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl << function_name - << " (ThriftDispatchProcessor *dispatch_processor," << endl << args_indent - << "ThriftProtocol *input_protocol," << endl << args_indent - << "ThriftProtocol *output_protocol," << endl << args_indent << "gchar *method_name," - << endl << args_indent << "gint32 sequence_id," << endl << args_indent - << "GError **error)" << endl; + f_service_ << "static gboolean" << '\n' << function_name + << " (ThriftDispatchProcessor *dispatch_processor," << '\n' << args_indent + << "ThriftProtocol *input_protocol," << '\n' << args_indent + << "ThriftProtocol *output_protocol," << '\n' << args_indent << "gchar *method_name," + << '\n' << args_indent << "gint32 sequence_id," << '\n' << args_indent + << "GError **error)" << '\n'; scope_up(f_service_); f_service_ << indent() << class_name_lc << "_process_function_def *" - << "process_function_def;" << endl; - f_service_ << indent() << "gboolean dispatch_result = FALSE;" << endl << endl << indent() - << class_name << " *self = " << class_name_uc << " (dispatch_processor);" << endl; + << "process_function_def;" << '\n'; + f_service_ << indent() << "gboolean dispatch_result = FALSE;" << '\n' << '\n' << indent() + << class_name << " *self = " << class_name_uc << " (dispatch_processor);" << '\n'; f_service_ << indent() << parent_class_name << "Class " - "*parent_class =" << endl; + "*parent_class =" << '\n'; indent_up(); f_service_ << indent() << "g_type_class_peek_parent (" << class_name_uc << "_GET_CLASS (self));" - << endl; + << '\n'; indent_down(); - f_service_ << endl + f_service_ << '\n' << indent() << "process_function_def = " - << "g_hash_table_lookup (self->process_map, method_name);" << endl - << indent() << "if (process_function_def != NULL)" << endl; + << "g_hash_table_lookup (self->process_map, method_name);" << '\n' + << indent() << "if (process_function_def != NULL)" << '\n'; scope_up(f_service_); args_indent = indent() + string(53, ' '); - f_service_ << indent() << "g_free (method_name);" << endl + f_service_ << indent() << "g_free (method_name);" << '\n' << indent() << "dispatch_result = " - << "(*process_function_def->function) (self," << endl - << args_indent << "sequence_id," << endl - << args_indent << "input_protocol," << endl - << args_indent << "output_protocol," << endl - << args_indent << "error);" << endl; + << "(*process_function_def->function) (self," << '\n' + << args_indent << "sequence_id," << '\n' + << args_indent << "input_protocol," << '\n' + << args_indent << "output_protocol," << '\n' + << args_indent << "error);" << '\n'; scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; scope_up(f_service_); // Method name not recognized; chain up to our parent processor---note the @@ -2622,160 +2620,165 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // will return an application exception to the caller if no class in the // hierarchy recognizes the method name f_service_ << indent() << "dispatch_result = parent_class->dispatch_call " - "(dispatch_processor," << endl; + "(dispatch_processor," << '\n'; args_indent = indent() + string(47, ' '); - f_service_ << args_indent << "input_protocol," << endl << args_indent << "output_protocol," - << endl << args_indent << "method_name," << endl << args_indent << "sequence_id," - << endl << args_indent << "error);" << endl; + f_service_ << args_indent << "input_protocol," << '\n' << args_indent << "output_protocol," + << '\n' << args_indent << "method_name," << '\n' << args_indent << "sequence_id," + << '\n' << args_indent << "error);" << '\n'; scope_down(f_service_); - f_service_ << endl << indent() << "return dispatch_result;" << endl; + f_service_ << '\n' << indent() << "return dispatch_result;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the processor's property setter function_name = class_name_lc + "_set_property"; args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "const GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_service_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "const GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << endl; + f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << '\n'; indent_up(); - f_service_ << indent() << "if (self->handler != NULL)" << endl; + f_service_ << indent() << "if (self->handler != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (self->handler);" << endl; + f_service_ << indent() << "g_object_unref (self->handler);" << '\n'; indent_down(); - f_service_ << indent() << "self->handler = g_value_get_object (value);" << endl << indent() - << "g_object_ref (self->handler);" << endl; + f_service_ << indent() << "self->handler = g_value_get_object (value);" << '\n' << indent() + << "g_object_ref (self->handler);" << '\n'; if (extends_service) { // Chain up to set the handler in every superclass as well - f_service_ << endl << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)->" - << endl; + f_service_ << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)->" + << '\n'; indent_up(); - f_service_ << indent() << "set_property (object, property_id, value, pspec);" << endl; + f_service_ << indent() << "set_property (object, property_id, value, pspec);" << '\n'; indent_down(); } - f_service_ << indent() << "break;" << endl; + f_service_ << indent() << "break;" << '\n'; indent_down(); - f_service_ << indent() << "default:" << endl; + f_service_ << indent() << "default:" << '\n'; indent_up(); f_service_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_service_); scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor's property getter function_name = class_name_lc + "_get_property"; args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_service_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << endl; + f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << '\n'; indent_up(); - f_service_ << indent() << "g_value_set_object (value, self->handler);" << endl << indent() - << "break;" << endl; + f_service_ << indent() << "g_value_set_object (value, self->handler);" << '\n' << indent() + << "break;" << '\n'; indent_down(); - f_service_ << indent() << "default:" << endl; + f_service_ << indent() << "default:" << '\n'; indent_up(); f_service_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_service_); scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generator the processor's dispose function - f_service_ << "static void" << endl << class_name_lc << "_dispose (GObject *gobject)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_dispose (GObject *gobject)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (gobject);" << endl - << endl << indent() << "if (self->handler != NULL)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (gobject);" << '\n' + << '\n' << indent() << "if (self->handler != NULL)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "g_object_unref (self->handler);" << endl << indent() - << "self->handler = NULL;" << endl; + f_service_ << indent() << "g_object_unref (self->handler);" << '\n' << indent() + << "self->handler = NULL;" << '\n'; scope_down(f_service_); - f_service_ << endl << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" + f_service_ << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" "->dispose (gobject);" - << endl; + << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor finalize function - f_service_ << "static void" << endl << class_name_lc << "_finalize (GObject *gobject)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_finalize (GObject *gobject)" << '\n'; scope_up(f_service_); f_service_ << indent() << this->nspace << service_name_ << "Processor *self = " << this->nspace_uc - << service_name_uc << "_PROCESSOR (gobject);" << endl << endl << indent() - << "thrift_safe_hash_table_destroy (self->process_map);" << endl << endl << indent() + << service_name_uc << "_PROCESSOR (gobject);" << '\n' << '\n' << indent() + << "thrift_safe_hash_table_destroy (self->process_map);" << '\n' << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" - "->finalize (gobject);" << endl; + "->finalize (gobject);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor instance initializer - f_service_ << "static void" << endl << class_name_lc << "_init (" << class_name << " *self)" - << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_init (" << class_name << " *self)" + << '\n'; scope_up(f_service_); if (functions.size() > 0) { - f_service_ << indent() << "guint index;" << endl - << endl; + f_service_ << indent() << "guint index;" << '\n' + << '\n'; } - f_service_ << indent() << "self->handler = NULL;" << endl << indent() + f_service_ << indent() << "self->handler = NULL;" << '\n' << indent() << "self->process_map = " - "g_hash_table_new (g_str_hash, g_str_equal);" << endl; + "g_hash_table_new (g_str_hash, g_str_equal);" << '\n'; if (functions.size() > 0) { args_indent = string(21, ' '); - f_service_ << endl + f_service_ << '\n' << indent() << "for (index = 0; index < " - << functions.size() << "; index += 1)" << endl; + << functions.size() << "; index += 1)" << '\n'; indent_up(); - f_service_ << indent() << "g_hash_table_insert (self->process_map," << endl + f_service_ << indent() << "g_hash_table_insert (self->process_map," << '\n' << indent() << args_indent - << class_name_lc << "_process_function_defs[index].name," << endl + << class_name_lc << "_process_function_defs[index].name," << '\n' << indent() << args_indent << "&" << class_name_lc << "_process_function_defs[index]" << ");" - << endl; + << '\n'; indent_down(); } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor class initializer - f_service_ << "static void" << endl << class_name_lc << "_class_init (" << class_name - << "Class *cls)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name + << "Class *cls)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl - << indent() << "ThriftDispatchProcessorClass *dispatch_processor_class =" << endl; + f_service_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' + << indent() << "ThriftDispatchProcessorClass *dispatch_processor_class =" << '\n'; indent_up(); - f_service_ << indent() << "THRIFT_DISPATCH_PROCESSOR_CLASS (cls);" << endl; + f_service_ << indent() << "THRIFT_DISPATCH_PROCESSOR_CLASS (cls);" << '\n'; indent_down(); - f_service_ << indent() << "GParamSpec *param_spec;" << endl << endl << indent() - << "gobject_class->dispose = " << class_name_lc << "_dispose;" << endl << indent() - << "gobject_class->finalize = " << class_name_lc << "_finalize;" << endl << indent() - << "gobject_class->set_property = " << class_name_lc << "_set_property;" << endl + f_service_ << indent() << "GParamSpec *param_spec;" << '\n' << '\n' << indent() + << "gobject_class->dispose = " << class_name_lc << "_dispose;" << '\n' << indent() + << "gobject_class->finalize = " << class_name_lc << "_finalize;" << '\n' << indent() + << "gobject_class->set_property = " << class_name_lc << "_set_property;" << '\n' << indent() << "gobject_class->get_property = " << class_name_lc << "_get_property;" - << endl << endl << indent() - << "dispatch_processor_class->dispatch_call = " << class_name_lc << "_dispatch_call;" - << endl << indent() << "cls->dispatch_call = " << class_name_lc << "_dispatch_call;" - << endl << endl << indent() << "param_spec = g_param_spec_object (\"handler\"," - << endl; + << '\n' << '\n'; + + if (extends_service) { + f_service_ << indent() << "dispatch_processor_class->dispatch_call = " << class_name_lc + << "_dispatch_call;" << '\n'; + } + + f_service_ << indent() << "cls->dispatch_call = " << class_name_lc << "_dispatch_call;" + << '\n' << '\n' << indent() << "param_spec = g_param_spec_object (\"handler\"," + << '\n'; args_indent = indent() + string(34, ' '); - f_service_ << args_indent << "\"Service handler implementation\"," << endl << args_indent - << "\"The service handler implementation \"" << endl << args_indent - << "\"to which method calls are dispatched.\"," << endl << args_indent - << this->nspace_uc + "TYPE_" + service_name_uc + "_HANDLER," << endl << args_indent - << "G_PARAM_READWRITE);" << endl; - f_service_ << indent() << "g_object_class_install_property (gobject_class," << endl; + f_service_ << args_indent << "\"Service handler implementation\"," << '\n' << args_indent + << "\"The service handler implementation \"" << '\n' << args_indent + << "\"to which method calls are dispatched.\"," << '\n' << args_indent + << this->nspace_uc + "TYPE_" + service_name_uc + "_HANDLER," << '\n' << args_indent + << "G_PARAM_READWRITE);" << '\n'; + f_service_ << indent() << "g_object_class_install_property (gobject_class," << '\n'; args_indent = indent() + string(33, ' '); - f_service_ << args_indent << "PROP_" << class_name_uc << "_HANDLER," << endl << args_indent - << "param_spec);" << endl; + f_service_ << args_indent << "PROP_" << class_name_uc << "_HANDLER," << '\n' << args_indent + << "param_spec);" << '\n'; scope_down(f_service_); } @@ -2807,60 +2810,60 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string args_indent; // write the instance definition - f_types_ << "struct _" << this->nspace << name << endl << "{ " << endl - << " ThriftStruct parent; " << endl << endl << " /* public */" << endl; + f_types_ << "struct _" << this->nspace << name << '\n' << "{ " << '\n' + << " ThriftStruct parent; " << '\n' << '\n' << " /* public */" << '\n'; // for each field, add a member variable vector::const_iterator m_iter; const vector& members = tstruct->get_members(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); - f_types_ << " " << type_name(t) << " " << (*m_iter)->get_name() << ";" << endl; + f_types_ << " " << type_name(t) << " " << (*m_iter)->get_name() << ";" << '\n'; if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - f_types_ << " gboolean __isset_" << (*m_iter)->get_name() << ";" << endl; + f_types_ << " gboolean __isset_" << (*m_iter)->get_name() << ";" << '\n'; } } // close the structure definition and create a typedef - f_types_ << "};" << endl << "typedef struct _" << this->nspace << name << " " << this->nspace - << name << ";" << endl << endl; + f_types_ << "};" << '\n' << "typedef struct _" << this->nspace << name << " " << this->nspace + << name << ";" << '\n' << '\n'; // write the class definition - f_types_ << "struct _" << this->nspace << name << "Class" << endl << "{" << endl - << " ThriftStructClass parent;" << endl << "};" << endl << "typedef struct _" - << this->nspace << name << "Class " << this->nspace << name << "Class;" << endl << endl; + f_types_ << "struct _" << this->nspace << name << "Class" << '\n' << "{" << '\n' + << " ThriftStructClass parent;" << '\n' << "};" << '\n' << "typedef struct _" + << this->nspace << name << "Class " << this->nspace << name << "Class;" << '\n' << '\n'; // write the standard GObject boilerplate - f_types_ << "GType " << this->nspace_lc << name_u << "_get_type (void);" << endl << "#define " + f_types_ << "GType " << this->nspace_lc << name_u << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << name_uc << " (" << this->nspace_lc << name_u - << "_get_type())" << endl << "#define " << this->nspace_uc << name_uc + << "_get_type())" << '\n' << "#define " << this->nspace_uc << name_uc << "(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" << name_uc - << ", " << this->nspace << name << "))" << endl << "#define " << this->nspace_uc + << ", " << this->nspace << name << "))" << '\n' << "#define " << this->nspace_uc << name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "_TYPE_" - << name_uc << ", " << this->nspace << name << "Class))" << endl << "#define " + << name_uc << ", " << this->nspace << name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << name_uc << "(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), " - << this->nspace_uc << "TYPE_" << name_uc << "))" << endl << "#define " << this->nspace_uc + << this->nspace_uc << "TYPE_" << name_uc << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc - << "TYPE_" << name_uc << "))" << endl << "#define " << this->nspace_uc << name_uc + << "TYPE_" << name_uc << "))" << '\n' << "#define " << this->nspace_uc << name_uc << "_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << name_uc << ", " << this->nspace << name << "Class))" << endl << endl; + << name_uc << ", " << this->nspace << name << "Class))" << '\n' << '\n'; // start writing the object implementation .c file // generate properties enum if (members.size() > 0) { - f_types_impl_ << "enum _" << class_name << "Properties" << endl << "{" << endl; + f_types_impl_ << "enum _" << class_name << "Properties" << '\n' << "{" << '\n'; indent_up(); f_types_impl_ << indent() << "PROP_" << class_name_uc << "_0"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string member_name_uc = to_upper_case(to_lower_case(initial_caps_to_underscores((*m_iter)->get_name()))); - f_types_impl_ << "," << endl << indent() << "PROP_" << class_name_uc << "_" << member_name_uc; + f_types_impl_ << "," << '\n' << indent() << "PROP_" << class_name_uc << "_" << member_name_uc; } - f_types_impl_ << endl; + f_types_impl_ << '\n'; indent_down(); - f_types_impl_ << "};" << endl << endl; + f_types_impl_ << "};" << '\n' << '\n'; } // generate struct I/O methods @@ -2874,12 +2877,12 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { // generate property setter function_name = class_name_lc + "_set_property"; args_indent = string(function_name.length() + 2, ' '); - f_types_impl_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent - << "const GValue *value," << endl << args_indent << "GParamSpec *pspec)" << endl; + f_types_impl_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent + << "const GValue *value," << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_types_impl_); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* member = (*m_iter); @@ -2890,7 +2893,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string property_identifier = "PROP_" + class_name_uc + "_" + member_name_uc; - f_types_impl_ << indent() << "case " << property_identifier + ":" << endl; + f_types_impl_ << indent() << "case " << property_identifier + ":" << '\n'; indent_up(); if (member_type->is_base_type()) { @@ -2900,7 +2903,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (base_type->get_base() == t_base_type::TYPE_STRING) { string release_function_name; - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { @@ -2912,7 +2915,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } f_types_impl_ << indent() << release_function_name << " (self->" << member_name << ");" - << endl; + << '\n'; indent_down(); } else { switch (base_type->get_base()) { @@ -2944,10 +2947,10 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } f_types_impl_ << indent() << "self->" << member_name << " = " << assign_function_name - << " (value);" << endl; + << " (value);" << '\n'; } else if (member_type->is_enum()) { f_types_impl_ << indent() << "self->" << member_name << " = g_value_get_int (value);" - << endl; + << '\n'; } else if (member_type->is_container()) { string release_function_name; string assign_function_name; @@ -2969,47 +2972,47 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { assign_function_name = "g_value_dup_boxed"; } - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); f_types_impl_ << indent() << release_function_name << " (self->" << member_name << ");" - << endl; + << '\n'; indent_down(); f_types_impl_ << indent() << "self->" << member_name << " = " << assign_function_name - << " (value);" << endl; + << " (value);" << '\n'; } else if (member_type->is_struct() || member_type->is_xception()) { - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_object_unref (self->" << member_name << ");" << endl; + f_types_impl_ << indent() << "g_object_unref (self->" << member_name << ");" << '\n'; indent_down(); f_types_impl_ << indent() << "self->" << member_name << " = g_value_dup_object (value);" - << endl; + << '\n'; } if (member->get_req() != t_field::T_REQUIRED) { - f_types_impl_ << indent() << "self->__isset_" << member_name << " = TRUE;" << endl; + f_types_impl_ << indent() << "self->__isset_" << member_name << " = TRUE;" << '\n'; } - f_types_impl_ << indent() << "break;" << endl << endl; + f_types_impl_ << indent() << "break;" << '\n' << '\n'; indent_down(); } - f_types_impl_ << indent() << "default:" << endl; + f_types_impl_ << indent() << "default:" << '\n'; indent_up(); f_types_impl_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_types_impl_); scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; // generate property getter function_name = class_name_lc + "_get_property"; args_indent = string(function_name.length() + 2, ' '); - f_types_impl_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_types_impl_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_types_impl_); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* member = (*m_iter); @@ -3070,26 +3073,26 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { "unrecognized type for struct member \"" + member_name + "\""; } - f_types_impl_ << indent() << "case " << property_identifier + ":" << endl; + f_types_impl_ << indent() << "case " << property_identifier + ":" << '\n'; indent_up(); f_types_impl_ << indent() << setter_function_name << " (value, self->" << member_name << ");" - << endl << indent() << "break;" << endl << endl; + << '\n' << indent() << "break;" << '\n' << '\n'; indent_down(); } - f_types_impl_ << indent() << "default:" << endl; + f_types_impl_ << indent() << "default:" << '\n'; indent_up(); f_types_impl_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_types_impl_); scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } // generate the instance init function - f_types_impl_ << "static void " << endl << this->nspace_lc << name_u << "_instance_init (" - << this->nspace << name << " * object)" << endl << "{" << endl; + f_types_impl_ << "static void " << '\n' << this->nspace_lc << name_u << "_instance_init (" + << this->nspace << name << " * object)" << '\n' << "{" << '\n'; indent_up(); // generate default-value structures for container-type members @@ -3109,9 +3112,9 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { // Generate an array with the list literal indent(f_types_impl_) << "static " << type_name(elem_type, false, true) << " __default_" - << member_name << "[" << list.size() << "] = " << endl; + << member_name << "[" << list.size() << "] = " << '\n'; indent_up(); - f_types_impl_ << indent() << constant_literal(member_type, member_value) << ";" << endl; + f_types_impl_ << indent() << constant_literal(member_type, member_value) << ";" << '\n'; indent_down(); constant_declaration_output = true; @@ -3129,15 +3132,15 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } if (constant_declaration_output) { if (string_list_constant_output) { - indent(f_types_impl_) << "unsigned int list_index;" << endl; + indent(f_types_impl_) << "unsigned int list_index;" << '\n'; } - f_types_impl_ << endl; + f_types_impl_ << '\n'; } // satisfy compilers with -Wall turned on - indent(f_types_impl_) << "/* satisfy -Wall */" << endl << indent() - << "THRIFT_UNUSED_VAR (object);" << endl; + indent(f_types_impl_) << "/* satisfy -Wall */" << '\n' << indent() + << "THRIFT_UNUSED_VAR (object);" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* member_type = (*m_iter)->get_type(); @@ -3153,7 +3156,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } else { dval += t->is_string() ? "NULL" : "0"; } - indent(f_types_impl_) << "object->" << (*m_iter)->get_name() << dval << ";" << endl; + indent(f_types_impl_) << "object->" << (*m_iter)->get_name() << dval << ";" << '\n'; } else if (t->is_struct()) { string name = (*m_iter)->get_name(); t_program* type_program = member_type->get_program(); @@ -3163,10 +3166,10 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string type_name_uc = to_upper_case(initial_caps_to_underscores(member_type->get_name())); indent(f_types_impl_) << "object->" << name << " = g_object_new (" << to_upper_case(type_nspace_prefix) << "TYPE_" << type_name_uc - << ", NULL);" << endl; + << ", NULL);" << '\n'; } else if (t->is_xception()) { string name = (*m_iter)->get_name(); - indent(f_types_impl_) << "object->" << name << " = NULL;" << endl; + indent(f_types_impl_) << "object->" << name << " = NULL;" << '\n'; } else if (t->is_container()) { string name = (*m_iter)->get_name(); string init_function; @@ -3184,7 +3187,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { init_function = generate_new_array_from_type(etype); } - indent(f_types_impl_) << "object->" << name << " = " << init_function << endl; + indent(f_types_impl_) << "object->" << name << " = " << init_function << '\n'; // Pre-populate the container with the specified default values, if any if ((*m_iter)->get_value()) { @@ -3196,17 +3199,17 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (is_numeric(etype)) { indent(f_types_impl_) << "g_array_append_vals (object->" << name << ", &__default_" << - name << ", " << list.size() << ");" << endl; + name << ", " << list.size() << ");" << '\n'; } else { indent(f_types_impl_) << "for (list_index = 0; list_index < " << list.size() << "; " << - "list_index += 1)" << endl; + "list_index += 1)" << '\n'; indent_up(); indent(f_types_impl_) << - "g_ptr_array_add (object->" << name << "," << endl << + "g_ptr_array_add (object->" << name << "," << '\n' << indent() << string(17, ' ') << "g_strdup (__default_" << - name << "[list_index]));" << endl; + name << "[list_index]));" << '\n'; indent_down(); } } @@ -3217,36 +3220,36 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { /* if not required, initialize the __isset variable */ if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent(f_types_impl_) << "object->__isset_" << (*m_iter)->get_name() << " = FALSE;" << endl; + indent(f_types_impl_) << "object->__isset_" << (*m_iter)->get_name() << " = FALSE;" << '\n'; } } indent_down(); - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << "}" << '\n' << '\n'; /* create the destructor */ - f_types_impl_ << "static void " << endl << this->nspace_lc << name_u - << "_finalize (GObject *object)" << endl << "{" << endl; + f_types_impl_ << "static void " << '\n' << this->nspace_lc << name_u + << "_finalize (GObject *object)" << '\n' << "{" << '\n'; indent_up(); f_types_impl_ << indent() << this->nspace << name << " *tobject = " << this->nspace_uc << name_uc - << " (object);" << endl << endl; + << " (object);" << '\n' << '\n'; - f_types_impl_ << indent() << "/* satisfy -Wall in case we don't use tobject */" << endl - << indent() << "THRIFT_UNUSED_VAR (tobject);" << endl; + f_types_impl_ << indent() << "/* satisfy -Wall in case we don't use tobject */" << '\n' + << indent() << "THRIFT_UNUSED_VAR (tobject);" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); if (t->is_container()) { string name = (*m_iter)->get_name(); if (t->is_map() || t->is_set()) { - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_hash_table_destroy (tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << "g_hash_table_destroy (tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } else if (t->is_list()) { t_type* etype = ((t_list*)t)->get_elem_type(); string destructor_function = "g_ptr_array_unref"; @@ -3273,59 +3276,59 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { destructor_function = "g_array_unref"; } - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << destructor_function << " (tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << destructor_function << " (tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } } else if (t->is_struct() || t->is_xception()) { string name = (*m_iter)->get_name(); // TODO: g_clear_object needs glib >= 2.28 - // f_types_impl_ << indent() << "g_clear_object (&(tobject->" << name << "));" << endl; + // f_types_impl_ << indent() << "g_clear_object (&(tobject->" << name << "));" << '\n'; // does g_object_unref the trick? - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_object_unref(tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << "g_object_unref(tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } else if (t->is_string()) { string name = (*m_iter)->get_name(); - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); f_types_impl_ << indent() << generate_free_func_from_type(t) << "(tobject->" << name << ");" - << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } } indent_down(); - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << "}" << '\n' << '\n'; // generate the class init function - f_types_impl_ << "static void" << endl << class_name_lc << "_class_init (" << class_name - << "Class * cls)" << endl; + f_types_impl_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name + << "Class * cls)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl + f_types_impl_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' << indent() << "ThriftStructClass *struct_class = " - << "THRIFT_STRUCT_CLASS (cls);" << endl << endl << indent() - << "struct_class->read = " << class_name_lc << "_read;" << endl << indent() - << "struct_class->write = " << class_name_lc << "_write;" << endl << endl + << "THRIFT_STRUCT_CLASS (cls);" << '\n' << '\n' << indent() + << "struct_class->read = " << class_name_lc << "_read;" << '\n' << indent() + << "struct_class->write = " << class_name_lc << "_write;" << '\n' << '\n' << indent() << "gobject_class->finalize = " << class_name_lc << "_finalize;" - << endl; + << '\n'; if (members.size() > 0) { f_types_impl_ << indent() << "gobject_class->get_property = " << class_name_lc - << "_get_property;" << endl << indent() - << "gobject_class->set_property = " << class_name_lc << "_set_property;" << endl; + << "_get_property;" << '\n' << indent() + << "gobject_class->set_property = " << class_name_lc << "_set_property;" << '\n'; // install a property for each member for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -3338,11 +3341,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string property_identifier = "PROP_" + class_name_uc + "_" + member_name_uc; - f_types_impl_ << endl << indent() << "g_object_class_install_property" << endl; + f_types_impl_ << '\n' << indent() << "g_object_class_install_property" << '\n'; indent_up(); args_indent = indent() + ' '; - f_types_impl_ << indent() << "(gobject_class," << endl << args_indent << property_identifier - << "," << endl << args_indent; + f_types_impl_ << indent() << "(gobject_class," << '\n' << args_indent << property_identifier + << "," << '\n' << args_indent; if (member_type->is_base_type()) { t_base_type::t_base base_type = ((t_base_type*)member_type)->get_base(); @@ -3350,27 +3353,27 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (base_type == t_base_type::TYPE_STRING) { if (((t_base_type*)member_type)->is_binary()) { args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << "G_TYPE_BYTE_ARRAY," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << "G_TYPE_BYTE_ARRAY," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; } else { args_indent += string(21, ' '); - f_types_impl_ << "g_param_spec_string (\"" << member_name << "\"," << endl - << args_indent << "NULL," << endl << args_indent << "NULL," << endl + f_types_impl_ << "g_param_spec_string (\"" << member_name << "\"," << '\n' + << args_indent << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent << ((member_value != NULL) ? "\"" + member_value->get_string() + "\"" - : "NULL") << "," << endl << args_indent - << "G_PARAM_READWRITE));" << endl; + : "NULL") << "," << '\n' << args_indent + << "G_PARAM_READWRITE));" << '\n'; } } else if (base_type == t_base_type::TYPE_BOOL) { args_indent += string(22, ' '); - f_types_impl_ << "g_param_spec_boolean (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent + f_types_impl_ << "g_param_spec_boolean (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent << (((member_value != NULL) && (member_value->get_integer() != 0)) ? "TRUE" - : "FALSE") << "," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + : "FALSE") << "," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; } else if ((base_type == t_base_type::TYPE_I8) || (base_type == t_base_type::TYPE_I16) || (base_type == t_base_type::TYPE_I32) || (base_type == t_base_type::TYPE_I64) || (base_type == t_base_type::TYPE_DOUBLE)) { @@ -3423,11 +3426,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } args_indent += string(param_spec_function_name.length() + 2, ' '); - f_types_impl_ << param_spec_function_name << " (\"" << member_name << "\"," << endl - << args_indent << "NULL," << endl << args_indent << "NULL," << endl - << args_indent << min_value << "," << endl << args_indent << max_value - << "," << endl << args_indent << default_value.str() << "," << endl - << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << param_spec_function_name << " (\"" << member_name << "\"," << '\n' + << args_indent << "NULL," << '\n' << args_indent << "NULL," << '\n' + << args_indent << min_value << "," << '\n' << args_indent << max_value + << "," << '\n' << args_indent << default_value.str() << "," << '\n' + << args_indent << "G_PARAM_READWRITE));" << '\n'; } indent_down(); @@ -3438,11 +3441,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { int max_value = (enum_max_value != nullptr) ? enum_max_value->get_value() : 0; args_indent += string(18, ' '); - f_types_impl_ << "g_param_spec_int (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << min_value << "," << endl << args_indent << max_value << "," << endl - << args_indent << min_value << "," << endl << args_indent - << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_int (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << min_value << "," << '\n' << args_indent << max_value << "," << '\n' + << args_indent << min_value << "," << '\n' << args_indent + << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_struct() || member_type->is_xception()) { t_program* type_program = member_type->get_program(); @@ -3454,9 +3457,9 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { + to_upper_case(initial_caps_to_underscores(member_type->get_name())); args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_object (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << param_type << "," << endl << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_object (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << param_type << "," << '\n' << args_indent << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_list()) { t_type* elem_type = ((t_list*)member_type)->get_elem_type(); @@ -3469,38 +3472,38 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << param_type << "," << endl << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << param_type << "," << '\n' << args_indent << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_set() || member_type->is_map()) { args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << "G_TYPE_HASH_TABLE," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << "G_TYPE_HASH_TABLE," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; indent_down(); } } } scope_down(f_types_impl_); - f_types_impl_ << endl; - - f_types_impl_ << "GType" << endl << this->nspace_lc << name_u << "_get_type (void)" << endl << "{" - << endl << " static GType type = 0;" << endl << endl << " if (type == 0) " << endl - << " {" << endl << " static const GTypeInfo type_info = " << endl << " {" - << endl << " sizeof (" << this->nspace << name << "Class)," << endl - << " NULL, /* base_init */" << endl << " NULL, /* base_finalize */" - << endl << " (GClassInitFunc) " << this->nspace_lc << name_u << "_class_init," - << endl << " NULL, /* class_finalize */" << endl - << " NULL, /* class_data */" << endl << " sizeof (" << this->nspace - << name << ")," << endl << " 0, /* n_preallocs */" << endl + f_types_impl_ << '\n'; + + f_types_impl_ << "GType" << '\n' << this->nspace_lc << name_u << "_get_type (void)" << '\n' << "{" + << '\n' << " static GType type = 0;" << '\n' << '\n' << " if (type == 0) " << '\n' + << " {" << '\n' << " static const GTypeInfo type_info = " << '\n' << " {" + << '\n' << " sizeof (" << this->nspace << name << "Class)," << '\n' + << " NULL, /* base_init */" << '\n' << " NULL, /* base_finalize */" + << '\n' << " (GClassInitFunc) " << this->nspace_lc << name_u << "_class_init," + << '\n' << " NULL, /* class_finalize */" << '\n' + << " NULL, /* class_data */" << '\n' << " sizeof (" << this->nspace + << name << ")," << '\n' << " 0, /* n_preallocs */" << '\n' << " (GInstanceInitFunc) " << this->nspace_lc << name_u << "_instance_init," - << endl << " NULL, /* value_table */" << endl << " };" << endl << endl - << " type = g_type_register_static (THRIFT_TYPE_STRUCT, " << endl + << '\n' << " NULL, /* value_table */" << '\n' << " };" << '\n' << '\n' + << " type = g_type_register_static (THRIFT_TYPE_STRUCT, " << '\n' << " \"" << this->nspace << name << "Type\"," - << endl << " &type_info, 0);" << endl << " }" - << endl << endl << " return type;" << endl << "}" << endl << endl; + << '\n' << " &type_info, 0);" << '\n' << " }" + << '\n' << '\n' << " return type;" << '\n' << "}" << '\n' << '\n'; } /** @@ -3521,59 +3524,59 @@ void t_c_glib_generator::generate_struct_writer(ostream& out, if (is_function) { error_ret = -1; - indent(out) << "static gint32" << endl << this->nspace_lc << name_u + indent(out) << "static gint32" << '\n' << this->nspace_lc << name_u << "_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" - << endl; + << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - out << indent() << "gint32 ret;" << endl << indent() << "gint32 xfer = 0;" << endl << endl; + out << indent() << "gint32 ret;" << '\n' << indent() << "gint32 xfer = 0;" << '\n' << '\n'; - indent(out) << this_get << endl; + indent(out) << this_get << '\n'; // satisfy -Wall in the case of an empty struct if (!this_get.empty()) { - indent(out) << "THRIFT_UNUSED_VAR (this_object);" << endl; + indent(out) << "THRIFT_UNUSED_VAR (this_object);" << '\n'; } out << indent() << "if ((ret = thrift_protocol_write_struct_begin (protocol, \"" << name - << "\", error)) < 0)" << endl << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl; + << "\", error)) < 0)" << '\n' << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL) { - indent(out) << "if (this_object->__isset_" << (*f_iter)->get_name() << " == TRUE) {" << endl; + indent(out) << "if (this_object->__isset_" << (*f_iter)->get_name() << " == TRUE) {" << '\n'; indent_up(); } out << indent() << "if ((ret = thrift_protocol_write_field_begin (protocol, " << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ", error)) < 0)" << endl << indent() << " return " << error_ret - << ";" << endl << indent() << "xfer += ret;" << endl; + << (*f_iter)->get_key() << ", error)) < 0)" << '\n' << indent() << " return " << error_ret + << ";" << '\n' << indent() << "xfer += ret;" << '\n'; generate_serialize_field(out, *f_iter, this_name, "", error_ret); - out << indent() << "if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" - << endl; + out << indent() << "if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" + << '\n'; if ((*f_iter)->get_req() == t_field::T_OPTIONAL) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // write the struct map - out << indent() << "if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << indent() << "if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << indent() << "if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << '\n'; if (is_function) { - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -3593,127 +3596,127 @@ void t_c_glib_generator::generate_struct_reader(ostream& out, if (is_function) { error_ret = -1; - indent(out) << "/* reads a " << name_u << " object */" << endl << "static gint32" << endl + indent(out) << "/* reads a " << name_u << " object */" << '\n' << "static gint32" << '\n' << this->nspace_lc << name_u - << "_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" << endl; + << "_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); // declare stack temp variables - out << indent() << "gint32 ret;" << endl << indent() << "gint32 xfer = 0;" << endl << indent() - << "gchar *name = NULL;" << endl << indent() << "ThriftType ftype;" << endl << indent() - << "gint16 fid;" << endl << indent() << "guint32 len = 0;" << endl << indent() - << "gpointer data = NULL;" << endl << indent() << this_get << endl; + out << indent() << "gint32 ret;" << '\n' << indent() << "gint32 xfer = 0;" << '\n' << indent() + << "gchar *name = NULL;" << '\n' << indent() << "ThriftType ftype;" << '\n' << indent() + << "gint16 fid;" << '\n' << indent() << "guint32 len = 0;" << '\n' << indent() + << "gpointer data = NULL;" << '\n' << indent() << this_get << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - indent(out) << "gboolean isset_" << (*f_iter)->get_name() << " = FALSE;" << endl; + indent(out) << "gboolean isset_" << (*f_iter)->get_name() << " = FALSE;" << '\n'; } } - out << endl; + out << '\n'; // satisfy -Wall in case we don't use some variables - out << indent() << "/* satisfy -Wall in case these aren't used */" << endl << indent() - << "THRIFT_UNUSED_VAR (len);" << endl << indent() << "THRIFT_UNUSED_VAR (data);" << endl; + out << indent() << "/* satisfy -Wall in case these aren't used */" << '\n' << indent() + << "THRIFT_UNUSED_VAR (len);" << '\n' << indent() << "THRIFT_UNUSED_VAR (data);" << '\n'; if (!this_get.empty()) { - out << indent() << "THRIFT_UNUSED_VAR (this_object);" << endl; + out << indent() << "THRIFT_UNUSED_VAR (this_object);" << '\n'; } - out << endl; + out << '\n'; // read the beginning of the structure marker - out << indent() << "/* read the struct begin marker */" << endl << indent() - << "if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0)" << endl - << indent() << "{" << endl << indent() << " if (name) g_free (name);" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << "}" << endl << indent() - << "xfer += ret;" << endl << indent() << "if (name) g_free (name);" << endl << indent() - << "name = NULL;" << endl << endl; + out << indent() << "/* read the struct begin marker */" << '\n' << indent() + << "if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0)" << '\n' + << indent() << "{" << '\n' << indent() << " if (name) g_free (name);" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << "}" << '\n' << indent() + << "xfer += ret;" << '\n' << indent() << "if (name) g_free (name);" << '\n' << indent() + << "name = NULL;" << '\n' << '\n'; // read the struct fields - out << indent() << "/* read the struct fields */" << endl << indent() << "while (1)" << endl; + out << indent() << "/* read the struct fields */" << '\n' << indent() << "while (1)" << '\n'; scope_up(out); // read beginning field marker - out << indent() << "/* read the beginning of a field */" << endl << indent() + out << indent() << "/* read the beginning of a field */" << '\n' << indent() << "if ((ret = thrift_protocol_read_field_begin (protocol, &name, &ftype, &fid, error)) < 0)" - << endl << indent() << "{" << endl << indent() << " if (name) g_free (name);" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "}" << endl << indent() - << "xfer += ret;" << endl << indent() << "if (name) g_free (name);" << endl << indent() - << "name = NULL;" << endl << endl; + << '\n' << indent() << "{" << '\n' << indent() << " if (name) g_free (name);" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "}" << '\n' << indent() + << "xfer += ret;" << '\n' << indent() << "if (name) g_free (name);" << '\n' << indent() + << "name = NULL;" << '\n' << '\n'; // check for field STOP marker - out << indent() << "/* break if we get a STOP field */" << endl << indent() - << "if (ftype == T_STOP)" << endl << indent() << "{" << endl << indent() << " break;" << endl - << indent() << "}" << endl << endl; + out << indent() << "/* break if we get a STOP field */" << '\n' << indent() + << "if (ftype == T_STOP)" << '\n' << indent() << "{" << '\n' << indent() << " break;" << '\n' + << indent() << "}" << '\n' << '\n'; // switch depending on the field type - indent(out) << "switch (fid)" << endl; + indent(out) << "switch (fid)" << '\n'; // start switch scope_up(out); // generate deserialization code for known types for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << (*f_iter)->get_key() << ":" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ")" << endl; - indent(out) << "{" << endl; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ")" << '\n'; + indent(out) << "{" << '\n'; indent_up(); // generate deserialize field generate_deserialize_field(out, *f_iter, this_name, "", error_ret, false); indent_down(); - out << indent() << "} else {" << endl << indent() - << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << " xfer += ret;" << endl - << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "} else {" << '\n' << indent() + << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << " xfer += ret;" << '\n' + << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // create the default case - out << indent() << "default:" << endl << indent() - << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << " xfer += ret;" << endl - << indent() << " break;" << endl; + out << indent() << "default:" << '\n' << indent() + << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << " xfer += ret;" << '\n' + << indent() << " break;" << '\n'; // end switch scope_down(out); // read field end marker - out << indent() << "if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl; + out << indent() << "if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n'; // end while loop scope_down(out); - out << endl; + out << '\n'; // read the end of the structure - out << indent() << "if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << '\n'; // if a required field is missing, throw an error for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl << indent() << "{" - << endl << indent() << " g_set_error (error, THRIFT_PROTOCOL_ERROR," << endl << indent() - << " THRIFT_PROTOCOL_ERROR_INVALID_DATA," << endl << indent() - << " \"missing field\");" << endl << indent() << " return -1;" << endl - << indent() << "}" << endl << endl; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << '\n' << indent() << "{" + << '\n' << indent() << " g_set_error (error, THRIFT_PROTOCOL_ERROR," << '\n' << indent() + << " THRIFT_PROTOCOL_ERROR_INVALID_DATA," << '\n' << indent() + << " \"missing field\");" << '\n' << indent() << " return -1;" << '\n' + << indent() << "}" << '\n' << '\n'; } } if (is_function) { - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; } // end the function/structure indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_c_glib_generator::generate_serialize_field(ostream& out, @@ -3773,9 +3776,9 @@ void t_c_glib_generator::generate_serialize_field(ostream& out, } else { out << "i32 (protocol, (gint32) " << name; } - out << ", error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl << endl; + out << ", error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n' << '\n'; } else { throw std::logic_error("DO NOT KNOW HOW TO SERIALIZE FIELD '" + name + "' TYPE '" + type_name(type)); @@ -3788,8 +3791,8 @@ void t_c_glib_generator::generate_serialize_struct(ostream& out, int error_ret) { (void)tstruct; out << indent() << "if ((ret = thrift_struct_write (THRIFT_STRUCT (" << prefix - << "), protocol, error)) < 0)" << endl << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl << endl; + << "), protocol, error)) < 0)" << '\n' << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n' << '\n'; } void t_c_glib_generator::generate_serialize_container(ostream& out, @@ -3826,39 +3829,39 @@ void t_c_glib_generator::generate_serialize_container(ostream& out, * This is because we may exit early before we get a chance to free the * GList. */ - out << indent() << "GList *key_list = NULL, *iter = NULL;" << endl - << indent() << tkey_name << tkey_ptr << "* keys;" << endl - << indent() << "int i = 0, key_count;" << endl - << endl + out << indent() << "GList *key_list = NULL, *iter = NULL;" << '\n' + << indent() << tkey_name << tkey_ptr << "* keys;" << '\n' + << indent() << "int i = 0, key_count;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_map_begin (protocol, " << type_to_enum(tkey) << ", " << type_to_enum(tval) << ", " << prefix << " ? " << "(gint32) g_hash_table_size ((GHashTable *) " << prefix << ") : 0" - << ", error)) < 0)" << endl; + << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << indent() << "if (" << prefix << ")" << endl + out << indent() << "xfer += ret;" << '\n' + << indent() << "if (" << prefix << ")" << '\n' << indent() << " g_hash_table_foreach ((GHashTable *) " << prefix - << ", thrift_hash_table_get_keys, &key_list);" << endl - << indent() << "key_count = g_list_length (key_list);" << endl + << ", thrift_hash_table_get_keys, &key_list);" << '\n' + << indent() << "key_count = g_list_length (key_list);" << '\n' << indent() << "keys = g_newa (" << tkey_name << tkey_ptr - << ", key_count);" << endl + << ", key_count);" << '\n' << indent() << "for (iter = g_list_first (key_list); iter; " - "iter = iter->next)" << endl; + "iter = iter->next)" << '\n'; indent_up(); out << indent() << "keys[i++] = (" << tkey_name << tkey_ptr - << ") iter->data;" << endl; + << ") iter->data;" << '\n'; indent_down(); - out << indent() << "g_list_free (key_list);" << endl - << endl - << indent() << "for (i = 0; i < key_count; ++i)" << endl; + out << indent() << "g_list_free (key_list);" << '\n' + << '\n' + << indent() << "for (i = 0; i < key_count; ++i)" << '\n'; scope_up(out); - out << indent() << keyname << " = keys[i];" << endl + out << indent() << keyname << " = keys[i];" << '\n' << indent() << valname << " = (" << tval_name << tval_ptr << ") g_hash_table_lookup (((GHashTable *) " << prefix - << "), (gpointer) " << keyname << ");" << endl - << endl; + << "), (gpointer) " << keyname << ");" << '\n' + << '\n'; generate_serialize_map_element(out, (t_map*)ttype, tkey_ptr + " " + keyname, @@ -3866,84 +3869,84 @@ void t_c_glib_generator::generate_serialize_container(ostream& out, error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_map_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_set()) { t_type* telem = ((t_set*)ttype)->get_elem_type(); string telem_name = type_name(telem); string telem_ptr = telem->is_string() || !telem->is_base_type() ? "" : "*"; - out << indent() << "GList *key_list = NULL, *iter = NULL;" << endl - << indent() << telem_name << telem_ptr << "* keys;" << endl - << indent() << "int i = 0, key_count;" << endl - << indent() << telem_name << telem_ptr << " elem;" << endl - << indent() << "gpointer value;" << endl - << indent() << "THRIFT_UNUSED_VAR (value);" << endl - << endl + out << indent() << "GList *key_list = NULL, *iter = NULL;" << '\n' + << indent() << telem_name << telem_ptr << "* keys;" << '\n' + << indent() << "int i = 0, key_count;" << '\n' + << indent() << telem_name << telem_ptr << " elem;" << '\n' + << indent() << "gpointer value;" << '\n' + << indent() << "THRIFT_UNUSED_VAR (value);" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_set_begin (protocol, " << type_to_enum(telem) << ", " << prefix << " ? " << "(gint32) g_hash_table_size ((GHashTable *) " << prefix << ") : 0" - << ", error)) < 0)" << endl; + << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << indent() << "if (" << prefix << ")" << endl + out << indent() << "xfer += ret;" << '\n' + << indent() << "if (" << prefix << ")" << '\n' << indent() << " g_hash_table_foreach ((GHashTable *) " << prefix - << ", thrift_hash_table_get_keys, &key_list);" << endl - << indent() << "key_count = g_list_length (key_list);" << endl + << ", thrift_hash_table_get_keys, &key_list);" << '\n' + << indent() << "key_count = g_list_length (key_list);" << '\n' << indent() << "keys = g_newa (" << telem_name << telem_ptr - << ", key_count);" << endl + << ", key_count);" << '\n' << indent() << "for (iter = g_list_first (key_list); iter; " - "iter = iter->next)" << endl; + "iter = iter->next)" << '\n'; indent_up(); out << indent() << "keys[i++] = (" << telem_name << telem_ptr - << ") iter->data;" << endl; + << ") iter->data;" << '\n'; indent_down(); - out << indent() << "g_list_free (key_list);" << endl - << endl - << indent() << "for (i = 0; i < key_count; ++i)" << endl; + out << indent() << "g_list_free (key_list);" << '\n' + << '\n' + << indent() << "for (i = 0; i < key_count; ++i)" << '\n'; scope_up(out); - out << indent() << "elem = keys[i];" << endl + out << indent() << "elem = keys[i];" << '\n' << indent() << "value = (gpointer) g_hash_table_lookup " - "(((GHashTable *) " << prefix << "), (gpointer) elem);" << endl - << endl; + "(((GHashTable *) " << prefix << "), (gpointer) elem);" << '\n' + << '\n'; generate_serialize_set_element(out, (t_set*)ttype, telem_ptr + "elem", error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_set_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_list()) { string length = "(" + prefix + " ? " + prefix + "->len : 0)"; string i = tmp("i"); - out << indent() << "guint " << i << ";" << endl - << endl + out << indent() << "guint " << i << ";" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_list_begin (protocol, " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", (gint32) " - << length << ", error)) < 0)" << endl; + << length << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl + out << indent() << "xfer += ret;" << '\n' << indent() << "for (" << i << " = 0; " << i << " < " << length << "; " - << i << "++)" << endl; + << i << "++)" << '\n'; scope_up(out); generate_serialize_list_element(out, (t_list*)ttype, prefix, i, error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_list_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } scope_down(out); @@ -4023,11 +4026,16 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, } else if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); if (tbase == t_base_type::TYPE_STRING) { - indent(out) << "if (" << name << " != NULL)" << endl << indent() << "{" << endl; + indent(out) << "if (" << name << " != NULL)" << '\n' << indent() << "{" << '\n'; indent_up(); - indent(out) << "g_free(" << name << ");" << endl << indent() << name << " = NULL;" << endl; + if (type->is_binary()) { + indent(out) << "g_byte_array_free(" << name << ", TRUE);" << '\n'; + } else { + indent(out) << "g_free(" << name << ");" << '\n'; + } + indent(out) << name << " = NULL;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } indent(out) << "if ((ret = thrift_protocol_read_"; @@ -4063,22 +4071,22 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, default: throw "compiler error: no C reader for base type " + t_base_type::t_base_name(tbase) + name; } - out << ", error)) < 0)" << endl; - out << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" - << endl; + out << ", error)) < 0)" << '\n'; + out << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" + << '\n'; // load the byte array with the data if (tbase == t_base_type::TYPE_STRING && type->is_binary()) { - indent(out) << name << " = g_byte_array_new();" << endl; - indent(out) << "g_byte_array_append (" << name << ", (guint8 *) data, (guint) len);" << endl; - indent(out) << "g_free (data);" << endl; + indent(out) << name << " = g_byte_array_new();" << '\n'; + indent(out) << "g_byte_array_append (" << name << ", (guint8 *) data, (guint) len);" << '\n'; + indent(out) << "g_free (data);" << '\n'; } } else if (type->is_enum()) { string t = tmp("ecast"); - out << indent() << "gint32 " << t << ";" << endl << indent() - << "if ((ret = thrift_protocol_read_i32 (protocol, &" << t << ", error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << indent() << name << " = (" << type_name(type) << ")" << t << ";" << endl; + out << indent() << "gint32 " << t << ";" << '\n' << indent() + << "if ((ret = thrift_protocol_read_i32 (protocol, &" << t << ", error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << indent() << name << " = (" << type_name(type) << ")" << t << ";" << '\n'; } else { throw std::logic_error("DO NOT KNOW HOW TO SERIALIZE FIELD '" + tfield->get_name() + "' TYPE '" + type_name(type)); @@ -4088,9 +4096,9 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, // set the isset variable. if the type is required, then set the // local variable indicating the value was set, so that we can do // validation later. if (prefix != "" && tfield->get_req() != t_field::T_REQUIRED) { - indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = TRUE;" << endl; + indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = TRUE;" << '\n'; } else if (prefix != "" && tfield->get_req() == t_field::T_REQUIRED) { - indent(out) << "isset_" << tfield->get_name() << " = TRUE;" << endl; + indent(out) << "isset_" << tfield->get_name() << " = TRUE;" << '\n'; } } @@ -4101,30 +4109,30 @@ void t_c_glib_generator::generate_deserialize_struct(ostream& out, bool allocate) { string name_uc = to_upper_case(initial_caps_to_underscores(tstruct->get_name())); if (tstruct->is_xception()) { - out << indent() << "/* This struct is an exception */" << endl; + out << indent() << "/* This struct is an exception */" << '\n'; allocate = true; } if (allocate) { - out << indent() << "if ( " << prefix << " != NULL)" << endl << indent() << "{" << endl; + out << indent() << "if ( " << prefix << " != NULL)" << '\n' << indent() << "{" << '\n'; indent_up(); - out << indent() << "g_object_unref (" << prefix << ");" << endl; + out << indent() << "g_object_unref (" << prefix << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << indent() << prefix << " = g_object_new (" << this->nspace_uc - << "TYPE_" << name_uc << ", NULL);" << endl; + out << indent() << "}" << '\n' << indent() << prefix << " = g_object_new (" << this->nspace_uc + << "TYPE_" << name_uc << ", NULL);" << '\n'; } out << indent() << "if ((ret = thrift_struct_read (THRIFT_STRUCT (" << prefix - << "), protocol, error)) < 0)" << endl << indent() << "{" << endl; + << "), protocol, error)) < 0)" << '\n' << indent() << "{" << '\n'; indent_up(); if (allocate) { - indent(out) << "g_object_unref (" << prefix << ");" << endl; + indent(out) << "g_object_unref (" << prefix << ");" << '\n'; if (tstruct->is_xception()) { - indent(out) << prefix << " = NULL;" << endl; + indent(out) << prefix << " = NULL;" << '\n'; } } - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << indent() << "xfer += ret;" << endl; + out << indent() << "}" << '\n' << indent() << "xfer += ret;" << '\n'; } void t_c_glib_generator::generate_deserialize_container(ostream& out, @@ -4134,80 +4142,80 @@ void t_c_glib_generator::generate_deserialize_container(ostream& out, scope_up(out); if (ttype->is_map()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType key_type;" << endl - << indent() << "ThriftType value_type;" << endl - << endl - << indent() << "/* read the map begin marker */" << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType key_type;" << '\n' + << indent() << "ThriftType value_type;" << '\n' + << '\n' + << indent() << "/* read the map begin marker */" << '\n' << indent() << "if ((ret = thrift_protocol_read_map_begin (protocol, " - "&key_type, &value_type, &size, error)) < 0)" << endl; + "&key_type, &value_type, &size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over map elements - out << indent() << "/* iterate through each of the map's fields */" << endl - << indent() << "for (i = 0; i < size; i++)" << endl; + out << indent() << "/* iterate through each of the map's fields */" << '\n' + << indent() << "for (i = 0; i < size; i++)" << '\n'; scope_up(out); generate_deserialize_map_element(out, (t_map*)ttype, prefix, error_ret); scope_down(out); - out << endl; + out << '\n'; // read map end - out << indent() << "/* read the map end marker */" << endl + out << indent() << "/* read the map end marker */" << '\n' << indent() << "if ((ret = thrift_protocol_read_map_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_set()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType element_type;" << endl - << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType element_type;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_read_set_begin (protocol, " - "&element_type, &size, error)) < 0)" << endl; + "&element_type, &size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over the elements - out << indent() << "/* iterate through the set elements */" << endl - << indent() << "for (i = 0; i < size; ++i)" << endl; + out << indent() << "/* iterate through the set elements */" << '\n' + << indent() << "for (i = 0; i < size; ++i)" << '\n'; scope_up(out); generate_deserialize_set_element(out, (t_set*)ttype, prefix, error_ret); scope_down(out); // read set end out << indent() << "if ((ret = thrift_protocol_read_set_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; } else if (ttype->is_list()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType element_type;" << endl - << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType element_type;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_read_list_begin (protocol, " - "&element_type,&size, error)) < 0)" << endl; + "&element_type,&size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over the elements - out << indent() << "/* iterate through list elements */" << endl - << indent() << "for (i = 0; i < size; i++)" << endl; + out << indent() << "/* iterate through list elements */" << '\n' + << indent() << "for (i = 0; i < size; i++)" << '\n'; scope_up(out); generate_deserialize_list_element(out, (t_list*)ttype, @@ -4218,11 +4226,11 @@ void t_c_glib_generator::generate_deserialize_container(ostream& out, // read list end out << indent() << "if ((ret = thrift_protocol_read_list_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } scope_down(out); @@ -4239,16 +4247,16 @@ void t_c_glib_generator::declare_local_variable(ostream& out, t_type* ttype, str if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; out << indent() << tname << ptr << " " << name << " = " - << generate_new_hash_from_type(tmap->get_key_type(), tmap->get_val_type()) << endl; + << generate_new_hash_from_type(tmap->get_key_type(), tmap->get_val_type()) << '\n'; } else if (ttype->is_list()) { t_list* tlist = (t_list*)ttype; out << indent() << tname << ptr << " " << name << " = " - << generate_new_array_from_type(tlist->get_elem_type()) << endl; + << generate_new_array_from_type(tlist->get_elem_type()) << '\n'; } else if (for_hash_table && ttype->is_enum()) { - out << indent() << tname << " " << name << ";" << endl; + out << indent() << tname << " " << name << ";" << '\n'; } else { out << indent() << tname << ptr << " " << name - << (ptr != "" ? " = g_new (" + tname + ", 1)" : " = NULL") << ";" << endl; + << (ptr != "" ? " = g_new (" + tname + ", 1)" : " = NULL") << ";" << '\n'; } } @@ -4259,7 +4267,7 @@ void t_c_glib_generator::declore_local_variable_for_write(ostream& out, ttype = get_true_type(ttype); string ptr = ttype->is_string() || !ttype->is_base_type() ? " " : "* "; string init_val = ttype->is_enum() ? "" : " = NULL"; - out << indent() << tname << ptr << name << init_val << ";" << endl; + out << indent() << tname << ptr << name << init_val << ";" << '\n'; } void t_c_glib_generator::generate_deserialize_map_element(ostream& out, @@ -4289,10 +4297,10 @@ void t_c_glib_generator::generate_deserialize_map_element(ostream& out, t_field fval(tval, tval_ptr + valname); generate_deserialize_field(out, &fval, "", "", error_ret); - indent(out) << "if (" << prefix << " && " << keyname << ")" << endl; + indent(out) << "if (" << prefix << " && " << keyname << ")" << '\n'; indent_up(); indent(out) << "g_hash_table_insert ((GHashTable *)" << prefix << ", (gpointer) " << keyname - << ", (gpointer) " << valname << ");" << endl; + << ", (gpointer) " << valname << ");" << '\n'; indent_down(); } @@ -4309,10 +4317,10 @@ void t_c_glib_generator::generate_deserialize_set_element(ostream& out, t_field felem(telem, telem_ptr + elem); generate_deserialize_field(out, &felem, "", "", error_ret); - indent(out) << "if (" << prefix << " && " << elem << ")" << endl; + indent(out) << "if (" << prefix << " && " << elem << ")" << '\n'; indent_up(); indent(out) << "g_hash_table_insert ((GHashTable *) " << prefix << ", (gpointer) " << elem - << ", (gpointer) " << elem << ");" << endl; + << ", (gpointer) " << elem << ");" << '\n'; indent_down(); } @@ -4334,10 +4342,10 @@ void t_c_glib_generator::generate_deserialize_list_element(ostream& out, if (ttype->is_void()) { throw std::runtime_error("compiler error: list element type cannot be void"); } else if (is_numeric(ttype)) { - indent(out) << "g_array_append_vals (" << prefix << ", " << elem << ", 1);" << endl; - indent(out) << "g_free (" << elem << ");" << endl; + indent(out) << "g_array_append_vals (" << prefix << ", " << elem << ", 1);" << '\n'; + indent(out) << "g_free (" << elem << ");" << '\n'; } else { - indent(out) << "g_ptr_array_add (" << prefix << ", " << elem << ");" << endl; + indent(out) << "g_ptr_array_add (" << prefix << ", " << elem << ");" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_cl_generator.cc b/compiler/cpp/src/thrift/generate/t_cl_generator.cc index e0dcc46af4b..409af1dd174 100644 --- a/compiler/cpp/src/thrift/generate/t_cl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_cl_generator.cc @@ -60,7 +60,7 @@ class t_cl_generator : public t_oop_generator { if(iter->first.compare("no_asd") == 0) { no_asd = true; } else if (iter->first.compare("sys_pref") == 0) { - system_prefix = iter->second; + system_prefix = iter->second; } else { throw "unknown option cl:" + iter->first; } @@ -130,9 +130,9 @@ void t_cl_generator::init_generator() { string f_vars_name = program_dir + "/" + program_name_ + "-vars.lisp"; f_types_.open(f_types_name); - f_types_ << cl_autogen_comment() << endl; + f_types_ << cl_autogen_comment() << '\n'; f_vars_.open(f_vars_name); - f_vars_ << cl_autogen_comment() << endl; + f_vars_ << cl_autogen_comment() << '\n'; package_def(f_types_); package_in(f_types_); @@ -141,7 +141,7 @@ void t_cl_generator::init_generator() { if (!no_asd) { string f_asd_name = program_dir + "/" + system_prefix + program_name_ + ".asd"; f_asd_.open(f_asd_name); - f_asd_ << cl_autogen_comment() << endl; + f_asd_ << cl_autogen_comment() << '\n'; asdf_def(f_asd_); } } @@ -197,13 +197,13 @@ string t_cl_generator::generated_package() { } void t_cl_generator::asdf_def(std::ostream &out) { - out << "(asdf:defsystem #:" << system_prefix << program_name_ << endl; + out << "(asdf:defsystem #:" << system_prefix << program_name_ << '\n'; indent_up(); out << indent() << render_includes() - << indent() << ":serial t" << endl + << indent() << ":serial t" << '\n' << indent() << ":components (" << "(:file \"" << program_name_ << "-types\") " - << "(:file \"" << program_name_ << "-vars\")))" << endl; + << "(:file \"" << program_name_ << "-vars\")))" << '\n'; indent_down(); } @@ -221,11 +221,11 @@ void t_cl_generator::package_def(std::ostream &out) { } out << ")"; } - out << ")" << endl << endl; + out << ")" << '\n' << '\n'; } void t_cl_generator::package_in(std::ostream &out) { - out << "(cl:in-package :" << package() << ")" << endl << endl; + out << "(cl:in-package :" << package() << ")" << '\n' << '\n'; } /** @@ -238,7 +238,7 @@ void t_cl_generator::generate_typedef(t_typedef* ttypedef) { } void t_cl_generator::generate_enum(t_enum* tenum) { - f_types_ << "(thrift:def-enum " << prefix(tenum->get_name()) << endl; + f_types_ << "(thrift:def-enum " << prefix(tenum->get_name()) << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -249,12 +249,12 @@ void t_cl_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { value = (*c_iter)->get_value(); - if(c_iter != constants.begin()) f_types_ << endl << indent() << " "; + if(c_iter != constants.begin()) f_types_ << '\n' << indent() << " "; f_types_ << "(\"" << (*c_iter)->get_name() << "\" . " << value << ")"; } indent_down(); - f_types_ << "))" << endl << endl; + f_types_ << "))" << '\n' << '\n'; } /** @@ -266,7 +266,7 @@ void t_cl_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); f_vars_ << "(thrift:def-constant " << prefix(name) << " " << render_const_value(type, value) << ")" - << endl << endl; + << '\n' << '\n'; } /** @@ -306,7 +306,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { out << (type->is_struct() ? "(make-instance '" : "(make-exception '") << - lowercase(type->get_name()) << " " << endl; + lowercase(type->get_name()) << " " << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -326,7 +326,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { } out << indent() << ":" << v_iter->first->get_string() << " " << - render_const_value(field_type, v_iter->second) << endl; + render_const_value(field_type, v_iter->second) << '\n'; } out << indent() << ")"; @@ -340,7 +340,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << endl << indent() + out << '\n' << indent() << "(cl:cons " << render_const_value(ktype, v_iter->first) << " " << render_const_value(vtype, v_iter->second) << ")"; } @@ -354,16 +354,16 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "(thrift:set" << endl; + out << "(thrift:set" << '\n'; } else { - out << "(thrift:list" << endl; + out << "(thrift:list" << '\n'; } indent_up(); indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << indent() << render_const_value(etype, *v_iter) << endl; + out << indent() << render_const_value(etype, *v_iter) << '\n'; } out << indent() << ")"; indent_down(); @@ -394,7 +394,7 @@ void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* ts t_type* type = (*m_iter)->get_type(); if (m_iter != members.begin()) { - out << endl << indent() << " "; + out << '\n' << indent() << " "; } out << "(" << prefix((*m_iter)->get_name()) << " " << ( (nullptr != value) ? render_const_value(type, value) : "nil" ) << @@ -421,16 +421,16 @@ void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* ts void t_cl_generator::generate_cl_struct(std::ostream& out, t_struct* tstruct, bool is_exception = false) { std::string name = type_name(tstruct); out << (is_exception ? "(thrift:def-exception " : "(thrift:def-struct ") << - prefix(name) << endl; + prefix(name) << '\n'; indent_up(); if ( tstruct->has_doc() ) { out << indent() ; - out << "\"" << cl_docstring(tstruct->get_doc()) << "\"" << endl; + out << "\"" << cl_docstring(tstruct->get_doc()) << "\"" << '\n'; } out << indent() ; generate_cl_struct_internal(out, tstruct, is_exception); indent_down(); - out << ")" << endl << endl; + out << ")" << '\n' << '\n'; } void t_cl_generator::generate_exception_sig(std::ostream& out, t_function* f) { @@ -454,7 +454,7 @@ void t_cl_generator::generate_service(t_service* tservice) { indent_up(); if ( tservice->has_doc()) { - f_types_ << endl << indent() + f_types_ << '\n' << indent() << "(:documentation \"" << cl_docstring(tservice->get_doc()) << "\")"; } @@ -465,23 +465,23 @@ void t_cl_generator::generate_service(t_service* tservice) { t_struct* exceptions = function->get_xceptions(); const vector& xmembers = exceptions->get_members(); - f_types_ << endl << indent() << "(:method " << prefix(fname); + f_types_ << '\n' << indent() << "(:method " << prefix(fname); f_types_ << " (" << signature << " " << typespec((*f_iter)->get_returntype()) << ")"; if (xmembers.size() > 0) { - f_types_ << endl << indent() << " :exceptions " ; + f_types_ << '\n' << indent() << " :exceptions " ; generate_exception_sig(f_types_, function); } if ( (*f_iter)->is_oneway() ) { - f_types_ << endl << indent() << " :oneway t"; + f_types_ << '\n' << indent() << " :oneway t"; } if ( (*f_iter)->has_doc() ) { - f_types_ << endl << indent() << " :documentation \"" + f_types_ << '\n' << indent() << " :documentation \"" << cl_docstring((*f_iter)->get_doc()) << "\""; } f_types_ << ")"; } - f_types_ << ")" << endl << endl; + f_types_ << ")" << '\n' << '\n'; indent_down(); } diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc index 9724fae80a6..013628de7c6 100644 --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc @@ -42,8 +42,6 @@ using std::ostream; using std::string; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * C++ code generator. This is legitimacy incarnate. * @@ -68,6 +66,7 @@ class t_cpp_generator : public t_oop_generator { gen_moveable_ = false; gen_no_ostream_operators_ = false; gen_no_skeleton_ = false; + gen_no_constructors_ = false; has_members_ = false; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { @@ -90,6 +89,8 @@ class t_cpp_generator : public t_oop_generator { gen_no_ostream_operators_ = true; } else if ( iter->first.compare("no_skeleton") == 0) { gen_no_skeleton_ = true; + } else if ( iter->first.compare("no_constructors") == 0) { + gen_no_constructors_ = true; } else { throw "unknown option cpp:" + iter->first; } @@ -126,7 +127,7 @@ class t_cpp_generator : public t_oop_generator { void generate_service(t_service* tservice) override; void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value); - std::string render_const_value(std::ostream& out, + std::string render_const_value(std::ostream* out, std::string name, t_type* type, t_const_value* value); @@ -143,14 +144,17 @@ class t_cpp_generator : public t_oop_generator { std::ostream& force_cpp_out, t_struct* tstruct, bool setters = true, - bool is_user_struct = false); + bool is_user_struct = false, + bool pointers = false); void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); + void generate_default_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); void generate_constructor_helper(std::ostream& out, t_struct* tstruct, bool is_excpetion, bool is_move); void generate_assignment_operator(std::ostream& out, t_struct* tstruct); + void generate_equality_operator(std::ostream& out, t_struct* tstruct); void generate_move_assignment_operator(std::ostream& out, t_struct* tstruct); void generate_assignment_helper(std::ostream& out, t_struct* tstruct, bool is_move); void generate_struct_reader(std::ostream& out, t_struct* tstruct, bool pointers = false); @@ -270,9 +274,12 @@ class t_cpp_generator : public t_oop_generator { bool is_complex_type(t_type* ttype) { ttype = get_true_type(ttype); - return ttype->is_container() || ttype->is_struct() || ttype->is_xception() + return ttype->is_container() // + || ttype->is_struct() // + || ttype->is_xception() || (ttype->is_base_type() - && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING)); + && ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) + || (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_UUID))); } void set_use_include_prefix(bool use_include_prefix) { use_include_prefix_ = use_include_prefix; } @@ -293,13 +300,19 @@ class t_cpp_generator : public t_oop_generator { (ttype->annotations_.find("cpp.customostream") != ttype->annotations_.end()); } - /** + /** * Determine if all fields of t_struct's storage do not throw * Move/Copy Constructors and Assignments applicable for 'noexcept' * Move defaults to 'noexcept' */ bool is_struct_storage_not_throwing(t_struct* tstruct) const; + /** + * Helper function to determine whether any of the members of our struct + * has a default value. + */ + bool has_field_with_default_value(t_struct* tstruct); + private: /** * Returns the include prefix to use for a file generated by program, or the @@ -309,7 +322,7 @@ class t_cpp_generator : public t_oop_generator { /** * Returns the legal program name to use for a file generated by program, if the - * program name contains dots then replace it with underscores, otherwise return the + * program name contains dots then replace it with underscores, otherwise return the * original program name. */ std::string get_legal_program_name(std::string program_name); @@ -362,10 +375,15 @@ class t_cpp_generator : public t_oop_generator { bool gen_no_default_operators_; /** - * True if we should generate skeleton. + * True if we should omit generating skeleton. */ bool gen_no_skeleton_; + /** + * True if we should omit generating constructors/destructors/assignment/destructors. + */ + bool gen_no_constructors_; + /** * True if thrift has member(s) */ @@ -429,69 +447,69 @@ void t_cpp_generator::init_generator() { f_types_tcc_ << autogen_comment(); // Start ifndef - f_types_ << "#ifndef " << program_name_ << "_TYPES_H" << endl << "#define " << program_name_ - << "_TYPES_H" << endl << endl; - f_types_tcc_ << "#ifndef " << program_name_ << "_TYPES_TCC" << endl << "#define " << program_name_ - << "_TYPES_TCC" << endl << endl; + f_types_ << "#ifndef " << program_name_ << "_TYPES_H" << '\n' << "#define " << program_name_ + << "_TYPES_H" << '\n' << '\n'; + f_types_tcc_ << "#ifndef " << program_name_ << "_TYPES_TCC" << '\n' << "#define " << program_name_ + << "_TYPES_TCC" << '\n' << '\n'; // Include base types - f_types_ << "#include " << endl - << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << endl; + f_types_ << "#include " << '\n' + << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << '\n'; // Include C++xx compatibility header - f_types_ << "#include " << endl; - f_types_ << "#include " << endl; + f_types_ << "#include " << '\n'; + f_types_ << "#include " << '\n'; // Include other Thrift includes const vector& includes = program_->get_includes(); for (auto include : includes) { f_types_ << "#include \"" << get_include_prefix(*include) << include->get_name() - << "_types.h\"" << endl; + << "_types.h\"" << '\n'; // XXX(simpkins): If gen_templates_ is enabled, we currently assume all // included files were also generated with templates enabled. f_types_tcc_ << "#include \"" << get_include_prefix(*include) << include->get_name() - << "_types.tcc\"" << endl; + << "_types.tcc\"" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; // Include custom headers const vector& cpp_includes = program_->get_cpp_includes(); for (const auto & cpp_include : cpp_includes) { if (cpp_include[0] == '<') { - f_types_ << "#include " << cpp_include << endl; + f_types_ << "#include " << cpp_include << '\n'; } else { - f_types_ << "#include \"" << cpp_include << "\"" << endl; + f_types_ << "#include \"" << cpp_include << "\"" << '\n'; } } - f_types_ << endl; + f_types_ << '\n'; // Include the types file f_types_impl_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.h\"" << endl << endl; + << "_types.h\"" << '\n' << '\n'; f_types_tcc_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.h\"" << endl << endl; + << "_types.h\"" << '\n' << '\n'; // The swap() code needs for std::swap() - f_types_impl_ << "#include " << endl; + f_types_impl_ << "#include " << '\n'; // for operator<< - f_types_impl_ << "#include " << endl << endl; - f_types_impl_ << "#include " << endl << endl; + f_types_impl_ << "#include " << '\n' << '\n'; + f_types_impl_ << "#include " << '\n' << '\n'; // Open namespace ns_open_ = namespace_open(program_->get_namespace("cpp")); ns_close_ = namespace_close(program_->get_namespace("cpp")); - f_types_ << ns_open_ << endl << endl; + f_types_ << ns_open_ << '\n' << '\n'; - f_types_impl_ << ns_open_ << endl << endl; + f_types_impl_ << ns_open_ << '\n' << '\n'; - f_types_tcc_ << ns_open_ << endl << endl; + f_types_tcc_ << ns_open_ << '\n' << '\n'; } /** @@ -499,21 +517,21 @@ void t_cpp_generator::init_generator() { */ void t_cpp_generator::close_generator() { // Close namespace - f_types_ << ns_close_ << endl << endl; - f_types_impl_ << ns_close_ << endl; - f_types_tcc_ << ns_close_ << endl << endl; + f_types_ << ns_close_ << '\n' << '\n'; + f_types_impl_ << ns_close_ << '\n'; + f_types_tcc_ << ns_close_ << '\n' << '\n'; // Include the types.tcc file from the types header file, // so clients don't have to explicitly include the tcc file. // TODO(simpkins): Make this a separate option. if (gen_templates_) { f_types_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.tcc\"" << endl << endl; + << "_types.tcc\"" << '\n' << '\n'; } // Close ifndef - f_types_ << "#endif" << endl; - f_types_tcc_ << "#endif" << endl; + f_types_ << "#endif" << '\n'; + f_types_tcc_ << "#endif" << '\n'; // Close output file f_types_.close(); @@ -535,7 +553,7 @@ void t_cpp_generator::close_generator() { void t_cpp_generator::generate_typedef(t_typedef* ttypedef) { generate_java_doc(f_types_, ttypedef); f_types_ << indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " - << ttypedef->get_symbolic() << ";" << endl << endl; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } void t_cpp_generator::generate_enum_constant_list(std::ostream& f, @@ -543,7 +561,7 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, const char* prefix, const char* suffix, bool include_values) { - f << " {" << endl; + f << " {" << '\n'; indent_up(); vector::const_iterator c_iter; @@ -552,7 +570,7 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, if (first) { first = false; } else { - f << "," << endl; + f << "," << '\n'; } generate_java_doc(f, *c_iter); indent(f) << prefix << (*c_iter)->get_name() << suffix; @@ -561,9 +579,9 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, } } - f << endl; + f << '\n'; indent_down(); - indent(f) << "};" << endl; + indent(f) << "};" << '\n'; } /** @@ -579,7 +597,7 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { if (!gen_pure_enums_) { enum_name = "type"; generate_java_doc(f_types_, tenum); - f_types_ << indent() << "struct " << tenum->get_name() << " {" << endl; + f_types_ << indent() << "struct " << tenum->get_name() << " {" << '\n'; indent_up(); } f_types_ << indent() << "enum " << enum_name; @@ -588,10 +606,10 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { if (!gen_pure_enums_) { indent_down(); - f_types_ << "};" << endl; + f_types_ << "};" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; /** Generate a character array of enum names for debugging purposes. @@ -608,13 +626,13 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { generate_enum_constant_list(f_types_impl_, constants, "\"", "\"", false); f_types_ << indent() << "extern const std::map _" << tenum->get_name() - << "_VALUES_TO_NAMES;" << endl << endl; + << "_VALUES_TO_NAMES;" << '\n' << '\n'; f_types_impl_ << indent() << "const std::map _" << tenum->get_name() << "_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(" << constants.size() << ", _k" << tenum->get_name() << "Values" << ", _k" << tenum->get_name() << "Names), " - << "::apache::thrift::TEnumIterator(-1, nullptr, nullptr));" << endl << endl; + << "::apache::thrift::TEnumIterator(-1, nullptr, nullptr));" << '\n' << '\n'; generate_enum_ostream_operator_decl(f_types_, tenum); generate_enum_ostream_operator(f_types_impl_, tenum); @@ -633,8 +651,8 @@ void t_cpp_generator::generate_enum_ostream_operator_decl(std::ostream& out, t_e } else { out << tenum->get_name() << "::type&"; } - out << " val);" << endl; - out << endl; + out << " val);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* tenum) { @@ -653,20 +671,20 @@ void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* scope_up(out); out << indent() << "std::map::const_iterator it = _" - << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl; - out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << endl; + << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << '\n'; + out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << '\n'; indent_up(); - out << indent() << "out << it->second;" << endl; + out << indent() << "out << it->second;" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "out << static_cast(val);" << endl; + out << indent() << "out << static_cast(val);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; - out << indent() << "return out;" << endl; + out << indent() << "return out;" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -677,8 +695,8 @@ void t_cpp_generator::generate_enum_to_string_helper_function_decl(std::ostream& } else { out << tenum->get_name() << "::type&"; } - out << " val);" << endl; - out << endl; + out << " val);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_enum_to_string_helper_function(std::ostream& out, t_enum* tenum) { @@ -693,19 +711,19 @@ void t_cpp_generator::generate_enum_to_string_helper_function(std::ostream& out, scope_up(out); out << indent() << "std::map::const_iterator it = _" - << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl; - out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << endl; + << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << '\n'; + out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << '\n'; indent_up(); - out << indent() << "return std::string(it->second);" << endl; + out << indent() << "return std::string(it->second);" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "return std::to_string(static_cast(val));" << endl; + out << indent() << "return std::to_string(static_cast(val));" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -727,28 +745,28 @@ void t_cpp_generator::generate_consts(std::vector consts) { f_consts_impl << autogen_comment(); // Start ifndef - f_consts << "#ifndef " << program_name_ << "_CONSTANTS_H" << endl << "#define " << program_name_ - << "_CONSTANTS_H" << endl << endl << "#include \"" << get_include_prefix(*get_program()) - << program_name_ << "_types.h\"" << endl << endl << ns_open_ << endl << endl; + f_consts << "#ifndef " << program_name_ << "_CONSTANTS_H" << '\n' << "#define " << program_name_ + << "_CONSTANTS_H" << '\n' << '\n' << "#include \"" << get_include_prefix(*get_program()) + << program_name_ << "_types.h\"" << '\n' << '\n' << ns_open_ << '\n' << '\n'; f_consts_impl << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_constants.h\"" << endl << endl << ns_open_ << endl << endl; + << "_constants.h\"" << '\n' << '\n' << ns_open_ << '\n' << '\n'; - f_consts << "class " << program_name_ << "Constants {" << endl << " public:" << endl << " " - << program_name_ << "Constants();" << endl << endl; + f_consts << "class " << program_name_ << "Constants {" << '\n' << " public:" << '\n' << " " + << program_name_ << "Constants();" << '\n' << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { string name = (*c_iter)->get_name(); t_type* type = (*c_iter)->get_type(); - f_consts << indent() << type_name(type) << " " << name << ";" << endl; + f_consts << indent() << type_name(type) << " " << name << ";" << '\n'; } indent_down(); - f_consts << "};" << endl; + f_consts << "};" << '\n'; f_consts_impl << "const " << program_name_ << "Constants g_" << program_name_ << "_constants;" - << endl << endl << program_name_ << "Constants::" << program_name_ - << "Constants() {" << endl; + << '\n' << '\n' << program_name_ << "Constants::" << program_name_ + << "Constants() {" << '\n'; indent_up(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { print_const_value(f_consts_impl, @@ -757,13 +775,13 @@ void t_cpp_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } indent_down(); - indent(f_consts_impl) << "}" << endl; + indent(f_consts_impl) << "}" << '\n'; - f_consts << endl << "extern const " << program_name_ << "Constants g_" << program_name_ - << "_constants;" << endl << endl << ns_close_ << endl << endl << "#endif" << endl; + f_consts << '\n' << "extern const " << program_name_ << "Constants g_" << program_name_ + << "_constants;" << '\n' << '\n' << ns_close_ << '\n' << '\n' << "#endif" << '\n'; f_consts.close(); - f_consts_impl << endl << ns_close_ << endl << endl; + f_consts_impl << '\n' << ns_close_ << '\n' << '\n'; f_consts_impl.close(); } } @@ -779,12 +797,12 @@ void t_cpp_generator::print_const_value(ostream& out, t_const_value* value) { type = get_true_type(type); if (type->is_base_type()) { - string v2 = render_const_value(out, name, type, value); - indent(out) << name << " = " << v2 << ";" << endl << endl; + string v2 = render_const_value(&out, name, type, value); + indent(out) << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { indent(out) << name << " = static_cast<" << type_name(type) << '>' - << '(' << value->get_integer() << ");" << endl << endl; + << '(' << value->get_integer() << ");" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -803,42 +821,42 @@ void t_cpp_generator::print_const_value(ostream& out, if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - string item_val = render_const_value(out, name, field_type, v_iter->second); - indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << endl; + string item_val = render_const_value(&out, name, field_type, v_iter->second); + indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << '\n'; if (is_nonrequired_field) { - indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << endl; + indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << '\n'; } } - out << endl; + out << '\n'; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string key = render_const_value(out, name, ktype, v_iter->first); - string item_val = render_const_value(out, name, vtype, v_iter->second); - indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << endl; + string key = render_const_value(&out, name, ktype, v_iter->first); + string item_val = render_const_value(&out, name, vtype, v_iter->second); + indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string item_val = render_const_value(out, name, etype, *v_iter); - indent(out) << name << ".push_back(" << item_val << ");" << endl; + string item_val = render_const_value(&out, name, etype, *v_iter); + indent(out) << name << ".push_back(" << item_val << ");" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string item_val = render_const_value(out, name, etype, *v_iter); - indent(out) << name << ".insert(" << item_val << ");" << endl; + string item_val = render_const_value(&out, name, etype, *v_iter); + indent(out) << name << ".insert(" << item_val << ");" << '\n'; } - out << endl; + out << '\n'; } else { throw "INVALID TYPE IN print_const_value: " + type->get_name(); } @@ -847,7 +865,7 @@ void t_cpp_generator::print_const_value(ostream& out, /** * */ -string t_cpp_generator::render_const_value(ostream& out, +string t_cpp_generator::render_const_value(ostream* out, string name, t_type* type, t_const_value* value) { @@ -884,10 +902,10 @@ string t_cpp_generator::render_const_value(ostream& out, } else if (type->is_enum()) { render << "static_cast<" << type_name(type) << '>' << '(' << value->get_integer() << ')'; - } else { + } else if (out) { string t = tmp("tmp"); - indent(out) << type_name(type) << " " << t << ";" << endl; - print_const_value(out, t, type, value); + indent(*out) << type_name(type) << " " << t << ";" << '\n'; + print_const_value(*out, t, type, value); render << t; } @@ -896,7 +914,7 @@ string t_cpp_generator::render_const_value(ostream& out, void t_cpp_generator::generate_forward_declaration(t_struct* tstruct) { // Forward declare struct def - f_types_ << indent() << "class " << tstruct->get_name() << ";" << endl << endl; + f_types_ << indent() << "class " << tstruct->get_name() << ";" << '\n' << '\n'; } /** @@ -908,19 +926,24 @@ void t_cpp_generator::generate_forward_declaration(t_struct* tstruct) { */ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) { generate_struct_declaration(f_types_, tstruct, is_exception, false, true, true, true, true); - generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true); + generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true, false); std::ostream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_); generate_struct_reader(out, tstruct); generate_struct_writer(out, tstruct); generate_struct_swap(f_types_impl_, tstruct); - generate_copy_constructor(f_types_impl_, tstruct, is_exception); - if (gen_moveable_) { - generate_move_constructor(f_types_impl_, tstruct, is_exception); + if (!gen_no_default_operators_) { + generate_equality_operator(f_types_impl_, tstruct); } - generate_assignment_operator(f_types_impl_, tstruct); - if (gen_moveable_) { - generate_move_assignment_operator(f_types_impl_, tstruct); + if (!gen_no_constructors_) { + generate_copy_constructor(f_types_impl_, tstruct, is_exception); + if (gen_moveable_) { + generate_move_constructor(f_types_impl_, tstruct, is_exception); + } + generate_assignment_operator(f_types_impl_, tstruct); + if (gen_moveable_) { + generate_move_assignment_operator(f_types_impl_, tstruct); + } } if (!has_custom_ostream(tstruct)) { @@ -934,6 +957,130 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) has_members_ = true; } +void t_cpp_generator::generate_equality_operator(std::ostream& out, t_struct* tstruct) { + // Get members + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + out << indent() << "bool " << tstruct->get_name() + << "::operator==(const " << tstruct->get_name() << " & " + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << '\n'; + scope_up(out); + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + // Most existing Thrift code does not use isset or optional/required, + // so we treat "default" fields as required. + if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { + out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." + << (*m_iter)->get_name() << "))" << '\n' << indent() << " return false;" << '\n'; + } else { + out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." + << (*m_iter)->get_name() << ")" << '\n' << indent() << " return false;" << '\n' + << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" + << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << '\n' + << indent() << " return false;" << '\n'; + } + } + indent(out) << "return true;" << '\n'; + scope_down(out); + out << '\n'; +} + +bool t_cpp_generator::has_field_with_default_value(t_struct* tstruct) +{ + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (is_reference(*m_iter) || t->is_string() || t->is_uuid()) { + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + return true; + } + } + } + + return false; +} + +void t_cpp_generator::generate_default_constructor(ostream& out, + t_struct* tstruct, + bool is_exception) { + // Get members + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + bool has_default_value = has_field_with_default_value(tstruct); + + std::string clsname_ctor = tstruct->get_name() + "::" + tstruct->get_name() + "()"; + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); + + // + // Start generating initializer list + // + + bool init_ctor = false; + std::string args_indent(" "); + + // Default-initialize TException, if it is our base type + if (is_exception) + { + out << '\n'; + indent(out) << " : "; + out << "TException()"; + init_ctor = true; + } + + // Default-initialize all members that should be initialized in + // the initializer block + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { + string dval; + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + dval += render_const_value(&out, (*m_iter)->get_name(), t, cv); + } else if (t->is_enum()) { + dval += "static_cast<" + type_name(t) + ">(0)"; + } else { + dval += (t->is_string() || is_reference(*m_iter) || t->is_uuid()) ? "" : "0"; + } + if (!init_ctor) { + init_ctor = true; + if(has_default_value) { + out << " : "; + } else { + out << '\n' << args_indent << ": "; + args_indent.append(" "); + } + } else { + out << ",\n" << args_indent; + } + + out << (*m_iter)->get_name() << "(" << dval << ")"; + } + } + + // + // Start generating body + // + + out << " {" << '\n'; + indent_up(); + // TODO(dreiss): When everything else in Thrift is perfect, + // do more of these in the initializer list. + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + print_const_value(out, (*m_iter)->get_name(), t, cv); + } + } + } + scope_down(out); +} + void t_cpp_generator::generate_copy_constructor(ostream& out, t_struct* tstruct, bool is_exception) { @@ -975,14 +1122,14 @@ void t_cpp_generator::generate_constructor_helper(ostream& out, out << "noexcept "; if (is_exception) out << ": TException() "; - out << "{" << endl; + out << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); // eliminate compiler unused warning if (members.empty()) - indent(out) << "(void) " << tmp_name << ";" << endl; + indent(out) << "(void) " << tmp_name << ";" << '\n'; vector::const_iterator f_iter; bool has_nonrequired_fields = false; @@ -991,17 +1138,17 @@ void t_cpp_generator::generate_constructor_helper(ostream& out, has_nonrequired_fields = true; indent(out) << (*f_iter)->get_name() << " = " << maybeMove( - tmp_name + "." + (*f_iter)->get_name(), + tmp_name + "." + (*f_iter)->get_name(), is_move && is_complex_type((*f_iter)->get_type())) - << ";" << endl; + << ";" << '\n'; } if (has_nonrequired_fields) { - indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl; + indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_cpp_generator::generate_assignment_operator(ostream& out, t_struct* tstruct) { @@ -1025,14 +1172,14 @@ void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct out << tmp_name << ") "; if(is_move || is_struct_storage_not_throwing(tstruct)) out << "noexcept "; - out << "{" << endl; + out << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); // eliminate compiler unused warning if (members.empty()) - indent(out) << "(void) " << tmp_name << ";" << endl; + indent(out) << "(void) " << tmp_name << ";" << '\n'; vector::const_iterator f_iter; bool has_nonrequired_fields = false; @@ -1041,17 +1188,17 @@ void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct has_nonrequired_fields = true; indent(out) << (*f_iter)->get_name() << " = " << maybeMove( - tmp_name + "." + (*f_iter)->get_name(), + tmp_name + "." + (*f_iter)->get_name(), is_move && is_complex_type((*f_iter)->get_type())) - << ";" << endl; + << ";" << '\n'; } if (has_nonrequired_fields) { - indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl; + indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << '\n'; } - indent(out) << "return *this;" << endl; + indent(out) << "return *this;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } /** @@ -1094,7 +1241,7 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, if (has_nonrequired_fields && (!pointers || read)) { - out << indent() << "typedef struct _" << tstruct->get_name() << "__isset {" << endl; + out << indent() << "typedef struct _" << tstruct->get_name() << "__isset {" << '\n'; indent_up(); indent(out) << "_" << tstruct->get_name() << "__isset() "; @@ -1111,127 +1258,74 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, out << ", " << (*m_iter)->get_name() << "(" << isSet << ")"; } } - out << " {}" << endl; + out << " {}" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent(out) << "bool " << (*m_iter)->get_name() << " :1;" << endl; + indent(out) << "bool " << (*m_iter)->get_name() << " :1;" << '\n'; } } indent_down(); - indent(out) << "} _" << tstruct->get_name() << "__isset;" << endl; + indent(out) << "} _" << tstruct->get_name() << "__isset;" << '\n'; } - out << endl; + out << '\n'; generate_java_doc(out, tstruct); // Open struct def - out << indent() << "class " << tstruct->get_name() << extends << " {" << endl << indent() - << " public:" << endl << endl; + out << indent() << "class " << tstruct->get_name() << extends << " {" << '\n' << indent() + << " public:" << '\n' << '\n'; indent_up(); - if (!pointers) { + if (!gen_no_constructors_ && !pointers) { bool ok_noexcept = is_struct_storage_not_throwing(tstruct); // Copy constructor indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&)" - << (ok_noexcept? " noexcept" : "") << ';' << endl; + << (ok_noexcept? " noexcept" : "") << ';' << '\n'; // Move constructor if (gen_moveable_) { - indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&) noexcept;" - << endl; + indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&) noexcept;" + << '\n'; } // Assignment Operator indent(out) << tstruct->get_name() << "& operator=(const " << tstruct->get_name() << "&)" - << (ok_noexcept? " noexcept" : "") << ';' << endl; + << (ok_noexcept? " noexcept" : "") << ';' << '\n'; // Move assignment operator if (gen_moveable_) { - indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&) noexcept;" - << endl; + indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&) noexcept;" + << '\n'; } - bool has_default_value = false; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (is_reference(*m_iter) || t->is_string()) { - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - has_default_value = true; - break; - } - } - } + bool has_default_value = has_field_with_default_value(tstruct); // Default constructor std::string clsname_ctor = tstruct->get_name() + "()"; - indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); - - bool init_ctor = false; - std::string args_indent( - indent().size() + clsname_ctor.size() + (has_default_value ? 3 : -1), ' '); - - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { - string dval; - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - dval += render_const_value(out, (*m_iter)->get_name(), t, cv); - } else if (t->is_enum()) { - dval += "static_cast<" + type_name(t) + ">(0)"; - } else { - dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; - } - if (!init_ctor) { - init_ctor = true; - if(has_default_value) { - out << " : "; - } else { - out << '\n' << args_indent << ": "; - args_indent.append(" "); - } - } else { - out << ",\n" << args_indent; - } - out << (*m_iter)->get_name() << "(" << dval << ")"; - } - } - out << " {" << endl; - indent_up(); - // TODO(dreiss): When everything else in Thrift is perfect, - // do more of these in the initializer list. - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - print_const_value(out, (*m_iter)->get_name(), t, cv); - } - } - } - scope_down(out); + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << '\n'; } - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { - out << endl << indent() << "virtual ~" << tstruct->get_name() << "() noexcept;" << endl; + if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + out << '\n' << indent(); + if (!gen_templates_) out << "virtual "; + out << "~" << tstruct->get_name() << "() noexcept;\n"; } // Declare all fields for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_java_doc(out, *m_iter); indent(out) << declare_field(*m_iter, - false, + !pointers && gen_no_constructors_, (pointers && !(*m_iter)->get_type()->is_xception()), - !read) << endl; + !read) << '\n'; } // Add the __isset data member if we need it, using the definition from above if (has_nonrequired_fields && (!pointers || read)) { - out << endl << indent() << "_" << tstruct->get_name() << "__isset __isset;" << endl; + out << '\n' << indent() << "_" << tstruct->get_name() << "__isset __isset;" << '\n'; } // Create a setter function for each field @@ -1240,104 +1334,88 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, continue; } if (is_reference((*m_iter))) { - out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" + out << '\n' << indent() << "void __set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" << type_name((*m_iter)->get_type(), false, false) << ">"; - out << " val);" << endl; + out << " val);" << '\n'; } else { - out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(" + out << '\n' << indent() << "void __set_" << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); - out << " val);" << endl; + out << " val);" << '\n'; } } - out << endl; + out << '\n'; if (!pointers) { // Should we generate default operators? if (!gen_no_default_operators_) { - // Generate an equality testing operator. Make it inline since the compiler - // will do a better job than we would when deciding whether to inline it. + // Generate an equality testing operator. out << indent() << "bool operator == (const " << tstruct->get_name() << " & " - << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << endl; - scope_up(out); - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - // Most existing Thrift code does not use isset or optional/required, - // so we treat "default" fields as required. - if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { - out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." - << (*m_iter)->get_name() << "))" << endl << indent() << " return false;" << endl; - } else { - out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." - << (*m_iter)->get_name() << ")" << endl << indent() << " return false;" << endl - << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" - << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << endl - << indent() << " return false;" << endl; - } - } - indent(out) << "return true;" << endl; - scope_down(out); + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const;" << '\n'; + out << indent() << "bool operator != (const " << tstruct->get_name() << " &rhs) const {" - << endl << indent() << " return !(*this == rhs);" << endl << indent() << "}" << endl - << endl; + << '\n' << indent() << " return !(*this == rhs);" << '\n' << indent() << "}" << '\n' + << '\n'; // Generate the declaration of a less-than operator. This must be // implemented by the application developer if they wish to use it. (They // will get a link error if they try to use it without an implementation.) - out << indent() << "bool operator < (const " << tstruct->get_name() << " & ) const;" << endl - << endl; + out << indent() << "bool operator < (const " << tstruct->get_name() << " & ) const;" << '\n' + << '\n'; } } if (read) { if (gen_templates_) { - out << indent() << "template " << endl << indent() - << "uint32_t read(Protocol_* iprot);" << endl; + out << indent() << "template " << '\n' << indent() + << "uint32_t read(Protocol_* iprot);" << '\n'; } else { out << indent() << "uint32_t read(" << "::apache::thrift::protocol::TProtocol* iprot)"; if(!is_exception && !extends.empty()) out << " override"; - out << ';' << endl; + out << ';' << '\n'; } } if (write) { if (gen_templates_) { - out << indent() << "template " << endl << indent() - << "uint32_t write(Protocol_* oprot) const;" << endl; + out << indent() << "template " << '\n' << indent() + << "uint32_t write(Protocol_* oprot) const;" << '\n'; } else { out << indent() << "uint32_t write(" << "::apache::thrift::protocol::TProtocol* oprot) const"; if(!is_exception && !extends.empty()) out << " override"; - out << ';' << endl; + out << ';' << '\n'; } } - out << endl; + out << '\n'; if (is_user_struct && !has_custom_ostream(tstruct)) { - out << indent() << "virtual "; + out << indent(); + if (!gen_templates_) out << "virtual "; generate_struct_print_method_decl(out, nullptr); - out << ";" << endl; + out << ";" << '\n'; } // std::exception::what() if (is_exception) { - out << indent() << "mutable std::string thriftTExceptionMessageHolder_;" << endl; + out << indent() << "mutable std::string thriftTExceptionMessageHolder_;" << '\n'; out << indent(); generate_exception_what_method_decl(out, tstruct, false); - out << ";" << endl; + out << ";" << '\n'; } indent_down(); - indent(out) << "};" << endl << endl; + indent(out) << "};" << '\n' << '\n'; if (swap) { // Generate a namespace-scope swap() function if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "void swap(" << tstruct->get_name() << " &a1, " << tstruct->get_name() - << " &a2);" << endl << endl; + << " &a2) noexcept;" << '\n' << '\n'; } else { out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name() - << " &b);" << endl << endl; + << " &b) noexcept;" << '\n' << '\n'; } } @@ -1350,51 +1428,60 @@ void t_cpp_generator::generate_struct_definition(ostream& out, ostream& force_cpp_out, t_struct* tstruct, bool setters, - bool is_user_struct) { + bool is_user_struct, + bool pointers) { // Get members vector::const_iterator m_iter; const vector& members = tstruct->get_members(); // Destructor - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { - force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name() - << "() noexcept {" << endl; + if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + force_cpp_out << '\n' << indent() << tstruct->get_name() << "::~" << tstruct->get_name() + << "() noexcept {" << '\n'; indent_up(); indent_down(); - force_cpp_out << indent() << "}" << endl << endl; + force_cpp_out << indent() << "}" << '\n' << '\n'; + } + + if (!gen_no_constructors_ && !pointers) + { + // 'force_cpp_out' always goes into the .cpp file, and never into a .tcc + // file in case templates are involved. Since the constructor is not templated, + // putting it into the (later included) .tcc file would cause ODR violations. + generate_default_constructor(force_cpp_out, tstruct, false); } // Create a setter function for each field if (setters) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (is_reference((*m_iter))) { - out << endl << indent() << "void " << tstruct->get_name() << "::__set_" + out << '\n' << indent() << "void " << tstruct->get_name() << "::__set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" << type_name((*m_iter)->get_type(), false, false) << ">"; - out << " val) {" << endl; + out << " val) {" << '\n'; } else { - out << endl << indent() << "void " << tstruct->get_name() << "::__set_" + out << '\n' << indent() << "void " << tstruct->get_name() << "::__set_" << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); - out << " val) {" << endl; + out << " val) {" << '\n'; } indent_up(); - out << indent() << "this->" << (*m_iter)->get_name() << " = val;" << endl; + out << indent() << "this->" << (*m_iter)->get_name() << " = val;" << '\n'; indent_down(); // assume all fields are required except optional fields. // for optional fields change __isset.name to true bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL; if (is_optional) { - out << indent() << indent() << "__isset." << (*m_iter)->get_name() << " = true;" << endl; + out << indent() << indent() << "__isset." << (*m_iter)->get_name() << " = true;" << '\n'; } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } if (is_user_struct) { generate_struct_ostream_operator(out, tstruct); } - out << endl; + out << '\n'; } /** @@ -1405,11 +1492,11 @@ void t_cpp_generator::generate_struct_definition(ostream& out, */ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bool pointers) { if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::read(Protocol_* iprot) {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl; + << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << '\n'; } indent_up(); @@ -1417,49 +1504,49 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo vector::const_iterator f_iter; // Declare stack tmp variables - out << endl - << indent() << "::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);" << endl - << indent() << "uint32_t xfer = 0;" << endl - << indent() << "std::string fname;" << endl - << indent() << "::apache::thrift::protocol::TType ftype;" << endl - << indent() << "int16_t fid;" << endl - << endl - << indent() << "xfer += iprot->readStructBegin(fname);" << endl - << endl - << indent() << "using ::apache::thrift::protocol::TProtocolException;" << endl - << endl; + out << '\n' + << indent() << "::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);" << '\n' + << indent() << "uint32_t xfer = 0;" << '\n' + << indent() << "std::string fname;" << '\n' + << indent() << "::apache::thrift::protocol::TType ftype;" << '\n' + << indent() << "int16_t fid;" << '\n' + << '\n' + << indent() << "xfer += iprot->readStructBegin(fname);" << '\n' + << '\n' + << indent() << "using ::apache::thrift::protocol::TProtocolException;" << '\n' + << '\n'; // Required variables aren't in __isset, so we need tmp vars to check them. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) - indent(out) << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl; + indent(out) << "bool isset_" << (*f_iter)->get_name() << " = false;" << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "xfer += iprot->readFieldBegin(fname, ftype, fid);" << endl; + indent(out) << "xfer += iprot->readFieldBegin(fname, ftype, fid);" << '\n'; // Check for field STOP marker - out << indent() << "if (ftype == ::apache::thrift::protocol::T_STOP) {" << endl << indent() - << " break;" << endl << indent() << "}" << endl; + out << indent() << "if (ftype == ::apache::thrift::protocol::T_STOP) {" << '\n' << indent() + << " break;" << '\n' << indent() << "}" << '\n'; if (fields.empty()) { - out << indent() << "xfer += iprot->skip(ftype);" << endl; + out << indent() << "xfer += iprot->skip(ftype);" << '\n'; } else { // Switch statement on the field we are reading - indent(out) << "switch (fid)" << endl; + indent(out) << "switch (fid)" << '\n'; scope_up(out); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << (*f_iter)->get_key() << ":" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); const char* isset_prefix = ((*f_iter)->get_req() != t_field::T_REQUIRED) ? "this->__isset." @@ -1471,8 +1558,8 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo // TODO(dreiss): Generate this code and "if" it out to make it easier // for people recompiling thrift to include it. out << - indent() << "if (" << isset_prefix << (*f_iter)->get_name() << ")" << endl << - indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + indent() << "if (" << isset_prefix << (*f_iter)->get_name() << ")" << '\n' << + indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; #endif if (pointers && !(*f_iter)->get_type()->is_xception()) { @@ -1480,44 +1567,44 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo } else { generate_deserialize_field(out, *f_iter, "this->"); } - out << indent() << isset_prefix << (*f_iter)->get_name() << " = true;" << endl; + out << indent() << isset_prefix << (*f_iter)->get_name() << " = true;" << '\n'; indent_down(); - out << indent() << "} else {" << endl << indent() << " xfer += iprot->skip(ftype);" << endl + out << indent() << "} else {" << '\n' << indent() << " xfer += iprot->skip(ftype);" << '\n' << // TODO(dreiss): Make this an option when thrift structs // have a common base class. - // indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl << - indent() << "}" << endl << indent() << "break;" << endl; + // indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n' << + indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "default:" << endl << indent() << " xfer += iprot->skip(ftype);" << endl - << indent() << " break;" << endl; + out << indent() << "default:" << '\n' << indent() << " xfer += iprot->skip(ftype);" << '\n' + << indent() << " break;" << '\n'; scope_down(out); } //!fields.empty() // Read field end marker - indent(out) << "xfer += iprot->readFieldEnd();" << endl; + indent(out) << "xfer += iprot->readFieldEnd();" << '\n'; scope_down(out); - out << endl << indent() << "xfer += iprot->readStructEnd();" << endl; + out << '\n' << indent() << "xfer += iprot->readStructEnd();" << '\n'; // Throw if any required fields are missing. // We do this after reading the struct end so that // there might possibly be a chance of continuing. - out << endl; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) - out << indent() << "if (!isset_" << (*f_iter)->get_name() << ')' << endl << indent() - << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ')' << '\n' << indent() + << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; } - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1532,33 +1619,33 @@ void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bo vector::const_iterator f_iter; if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::write(Protocol_* oprot) const {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << '\n'; } indent_up(); - out << indent() << "uint32_t xfer = 0;" << endl; + out << indent() << "uint32_t xfer = 0;" << '\n'; - indent(out) << "::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);" << endl; - indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + indent(out) << "::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);" << '\n'; + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool check_if_set = (*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_type()->is_xception(); if (check_if_set) { - out << endl << indent() << "if (this->__isset." << (*f_iter)->get_name() << ") {" << endl; + out << '\n' << indent() << "if (this->__isset." << (*f_iter)->get_name() << ") {" << '\n'; indent_up(); } else { - out << endl; + out << '\n'; } // Write field header out << indent() << "xfer += oprot->writeFieldBegin(" << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ");" << endl; + << (*f_iter)->get_key() << ");" << '\n'; // Write field contents if (pointers && !(*f_iter)->get_type()->is_xception()) { generate_serialize_field(out, *f_iter, "(*(this->", "))"); @@ -1566,22 +1653,22 @@ void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bo generate_serialize_field(out, *f_iter, "this->"); } // Write field closer - indent(out) << "xfer += oprot->writeFieldEnd();" << endl; + indent(out) << "xfer += oprot->writeFieldEnd();" << '\n'; if (check_if_set) { indent_down(); indent(out) << '}'; } } - out << endl; + out << '\n'; // Write the struct map - out << indent() << "xfer += oprot->writeFieldStop();" << endl << indent() - << "xfer += oprot->writeStructEnd();" << endl << indent() - << "return xfer;" << endl; + out << indent() << "xfer += oprot->writeFieldStop();" << '\n' << indent() + << "xfer += oprot->writeStructEnd();" << '\n' << indent() + << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1600,35 +1687,35 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, vector::const_iterator f_iter; if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::write(Protocol_* oprot) const {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << '\n'; } indent_up(); - out << endl << indent() << "uint32_t xfer = 0;" << endl << endl; + out << '\n' << indent() << "uint32_t xfer = 0;" << '\n' << '\n'; - indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl; + out << "(this->__isset." << (*f_iter)->get_name() << ") {" << '\n'; indent_up(); // Write field header out << indent() << "xfer += oprot->writeFieldBegin(" << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ");" << endl; + << (*f_iter)->get_key() << ");" << '\n'; // Write field contents if (pointers) { generate_serialize_field(out, *f_iter, "(*(this->", "))"); @@ -1636,18 +1723,18 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, generate_serialize_field(out, *f_iter, "this->"); } // Write field closer - indent(out) << "xfer += oprot->writeFieldEnd();" << endl; + indent(out) << "xfer += oprot->writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } // Write the struct map - out << endl << indent() << "xfer += oprot->writeFieldStop();" << endl << indent() - << "xfer += oprot->writeStructEnd();" << endl << indent() << "return xfer;" << endl; + out << '\n' << indent() << "xfer += oprot->writeFieldStop();" << '\n' << indent() + << "xfer += oprot->writeStructEnd();" << '\n' << indent() << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1659,10 +1746,10 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "void swap(" << tstruct->get_name() << " &a1, " << tstruct->get_name() - << " &a2) {" << endl; + << " &a2) noexcept {" << '\n'; } else { out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name() - << " &b) {" << endl; + << " &b) noexcept {" << '\n'; } indent_up(); @@ -1670,7 +1757,7 @@ void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { // Let argument-dependent name lookup find the correct swap() function to // use based on the argument types. If none is found in the arguments' // namespaces, fall back to ::std::swap(). - out << indent() << "using ::std::swap;" << endl; + out << indent() << "using ::std::swap;" << '\n'; bool has_nonrequired_fields = false; const vector& fields = tstruct->get_members(); @@ -1681,41 +1768,41 @@ void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "swap(a1." << tfield->get_name() << ", a2." << tfield->get_name() << ");" - << endl; + << '\n'; } else { out << indent() << "swap(a." << tfield->get_name() << ", b." << tfield->get_name() << ");" - << endl; + << '\n'; } } if (has_nonrequired_fields) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { - out << indent() << "swap(a1.__isset, a2.__isset);" << endl; + out << indent() << "swap(a1.__isset, a2.__isset);" << '\n'; } else { - out << indent() << "swap(a.__isset, b.__isset);" << endl; + out << indent() << "swap(a.__isset, b.__isset);" << '\n'; } } // handle empty structs if (fields.size() == 0) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { - out << indent() << "(void) a1;" << endl; - out << indent() << "(void) a2;" << endl; + out << indent() << "(void) a1;" << '\n'; + out << indent() << "(void) a2;" << '\n'; } else { - out << indent() << "(void) a;" << endl; - out << indent() << "(void) b;" << endl; + out << indent() << "(void) a;" << '\n'; + out << indent() << "(void) b;" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_cpp_generator::generate_struct_ostream_operator_decl(std::ostream& out, t_struct* tstruct) { out << "std::ostream& operator<<(std::ostream& out, const " << tstruct->get_name() - << "& obj);" << endl; - out << endl; + << "& obj);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_struct* tstruct) { @@ -1723,12 +1810,12 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_stru // thrift defines this behavior out << "std::ostream& operator<<(std::ostream& out, const " << tstruct->get_name() - << "& obj)" << endl; + << "& obj)" << '\n'; scope_up(out); - out << indent() << "obj.printTo(out);" << endl - << indent() << "return out;" << endl; + out << indent() << "obj.printTo(out);" << '\n' + << indent() << "return out;" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -1793,7 +1880,7 @@ void generate_fields(std::ostream& out, } generate_field(out, *it); - out << ";" << endl; + out << ";" << '\n'; } } } @@ -1804,17 +1891,17 @@ void generate_fields(std::ostream& out, void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* tstruct) { out << indent(); generate_struct_print_method_decl(out, tstruct); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "using ::apache::thrift::to_string;" << endl; - out << indent() << "out << \"" << tstruct->get_name() << "(\";" << endl; + out << indent() << "using ::apache::thrift::to_string;" << '\n'; + out << indent() << "out << \"" << tstruct->get_name() << "(\";" << '\n'; struct_ostream_operator_generator::generate_fields(out, tstruct->get_members(), indent()); - out << indent() << "out << \")\";" << endl; + out << indent() << "out << \")\";" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; } /** @@ -1823,29 +1910,29 @@ void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* void t_cpp_generator::generate_exception_what_method(std::ostream& out, t_struct* tstruct) { out << indent(); generate_exception_what_method_decl(out, tstruct, true); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); - out << indent() << "std::stringstream ss;" << endl; - out << indent() << "ss << \"TException - service has thrown: \" << *this;" << endl; - out << indent() << "this->thriftTExceptionMessageHolder_ = ss.str();" << endl; - out << indent() << "return this->thriftTExceptionMessageHolder_.c_str();" << endl; + out << indent() << "std::stringstream ss;" << '\n'; + out << indent() << "ss << \"TException - service has thrown: \" << *this;" << '\n'; + out << indent() << "this->thriftTExceptionMessageHolder_ = ss.str();" << '\n'; + out << indent() << "return this->thriftTExceptionMessageHolder_.c_str();" << '\n'; indent_down(); - out << indent() << "} catch (const std::exception&) {" << endl; + out << indent() << "} catch (const std::exception&) {" << '\n'; indent_up(); out << indent() << "return \"TException - service has thrown: " << tstruct->get_name() << "\";" - << endl; + << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; } /** @@ -1865,30 +1952,30 @@ void t_cpp_generator::generate_service(t_service* tservice) { // Print header file includes f_header_ << autogen_comment(); - f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl - << endl; + f_header_ << "#ifndef " << svcname << "_H" << '\n' << "#define " << svcname << "_H" << '\n' + << '\n'; if (gen_cob_style_) { - f_header_ << "#include " << endl // TMemoryBuffer - << "#include " << endl - << "namespace apache { namespace thrift { namespace async {" << endl - << "class TAsyncChannel;" << endl << "}}}" << endl; + f_header_ << "#include " << '\n' // TMemoryBuffer + << "#include " << '\n' + << "namespace apache { namespace thrift { namespace async {" << '\n' + << "class TAsyncChannel;" << '\n' << "}}}" << '\n'; } - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; if (gen_cob_style_) { - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; } - f_header_ << "#include " << endl; - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; + f_header_ << "#include " << '\n'; f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" - << endl; + << '\n'; t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".h\"" << endl; + << extends_service->get_name() << ".h\"" << '\n'; } - f_header_ << endl << ns_open_ << endl << endl; + f_header_ << '\n' << ns_open_ << '\n' << '\n'; f_header_ << "#ifdef _MSC_VER\n" " #pragma warning( push )\n" @@ -1899,30 +1986,30 @@ void t_cpp_generator::generate_service(t_service* tservice) { string f_service_name = get_out_dir() + svcname + ".cpp"; f_service_.open(f_service_name.c_str()); f_service_ << autogen_comment(); - f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl; + f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n'; if (gen_cob_style_) { - f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << '\n'; } if (gen_templates_) { f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" - << endl; + << '\n'; string f_service_tcc_name = get_out_dir() + svcname + ".tcc"; f_service_tcc_.open(f_service_tcc_name.c_str()); f_service_tcc_ << autogen_comment(); f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" - << endl; + << '\n'; - f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" - << endl << endl; + f_service_tcc_ << "#ifndef " << svcname << "_TCC" << '\n' << "#define " << svcname << "_TCC" + << '\n' << '\n'; if (gen_cob_style_) { - f_service_tcc_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + f_service_tcc_ << "#include \"thrift/async/TAsyncChannel.h\"" << '\n'; } } - f_service_ << endl << ns_open_ << endl << endl; - f_service_tcc_ << endl << ns_open_ << endl << endl; + f_service_ << '\n' << ns_open_ << '\n' << '\n'; + f_service_tcc_ << '\n' << ns_open_ << '\n' << '\n'; // Generate all the components generate_service_interface(tservice, ""); @@ -1959,19 +2046,19 @@ void t_cpp_generator::generate_service(t_service* tservice) { "#endif\n\n"; // Close the namespace - f_service_ << ns_close_ << endl << endl; - f_service_tcc_ << ns_close_ << endl << endl; - f_header_ << ns_close_ << endl << endl; + f_service_ << ns_close_ << '\n' << '\n'; + f_service_tcc_ << ns_close_ << '\n' << '\n'; + f_header_ << ns_close_ << '\n' << '\n'; // TODO(simpkins): Make this a separate option if (gen_templates_) { - f_header_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" << endl + f_header_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" << '\n' << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.tcc\"" << endl << endl; + << "_types.tcc\"" << '\n' << '\n'; } - f_header_ << "#endif" << endl; - f_service_tcc_ << "#endif" << endl; + f_header_ << "#endif" << '\n'; + f_service_tcc_ << "#endif" << '\n'; // Close the files f_service_tcc_.close(); @@ -2000,9 +2087,10 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { generate_struct_definition(out, f_service_, ts, false); generate_struct_reader(out, ts); generate_struct_writer(out, ts); + ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs"); generate_struct_declaration(f_header_, ts, false, true, false, true); - generate_struct_definition(out, f_service_, ts, false); + generate_struct_definition(out, f_service_, ts, false, false, true); generate_struct_writer(out, ts, true); ts->set_name(name_orig); @@ -2024,9 +2112,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty if (gen_templates_) { client_name += "T"; service_if_name += "T"; - indent(f_header_) << "template " << endl; + indent(f_header_) << "template " << '\n'; } - indent(f_header_) << "class " << client_name << ";" << endl << endl; + indent(f_header_) << "class " << client_name << ";" << '\n' << '\n'; } string extends = ""; @@ -2040,31 +2128,31 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } if (style == "CobCl" && gen_templates_) { - f_header_ << "template " << endl; + f_header_ << "template " << '\n'; } generate_java_doc(f_header_, tservice); - f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; + f_header_ << "class " << service_if_name << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl; + f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { if ((*f_iter)->has_doc()) - f_header_ << endl; + f_header_ << '\n'; generate_java_doc(f_header_, *f_iter); - f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl; + f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << '\n'; } indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (style == "CobCl" && gen_templates_) { // generate a backwards-compatible typedef for clients that do not // know about the new template-style code f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " - << service_name_ << style << "If;" << endl << endl; + << service_name_ << style << "If;" << '\n' << '\n'; } } @@ -2107,37 +2195,37 @@ void t_cpp_generator::generate_service_interface_factory(t_service* tservice, st extends = " : virtual public " + type_name(tservice->get_extends()) + style + "IfFactory"; } - f_header_ << "class " << factory_name << extends << " {" << endl << " public:" << endl; + f_header_ << "class " << factory_name << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "typedef " << service_if_name << " Handler;" << endl << endl << indent() - << "virtual ~" << factory_name << "() {}" << endl << endl << indent() << "virtual " + f_header_ << indent() << "typedef " << service_if_name << " Handler;" << '\n' << '\n' << indent() + << "virtual ~" << factory_name << "() {}" << '\n' << '\n' << indent() << "virtual " << service_if_name << "* getHandler(" << "const ::apache::thrift::TConnectionInfo& connInfo)" - << (extends.empty() ? "" : " override") << " = 0;" << endl << indent() + << (extends.empty() ? "" : " override") << " = 0;" << '\n' << indent() << "virtual void releaseHandler(" << base_if_name << "* /* handler */)" - << (extends.empty() ? "" : " override") << " = 0;" << endl << indent(); + << (extends.empty() ? "" : " override") << " = 0;" << '\n' << indent(); indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; // Generate the singleton factory class string singleton_factory_name = service_if_name + "SingletonFactory"; f_header_ << "class " << singleton_factory_name << " : virtual public " << factory_name << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); f_header_ << indent() << singleton_factory_name << "(const ::std::shared_ptr<" << service_if_name - << ">& iface) : iface_(iface) {}" << endl << indent() << "virtual ~" - << singleton_factory_name << "() {}" << endl << endl << indent() << "virtual " + << ">& iface) : iface_(iface) {}" << '\n' << indent() << "virtual ~" + << singleton_factory_name << "() {}" << '\n' << '\n' << indent() << "virtual " << service_if_name << "* getHandler(" - << "const ::apache::thrift::TConnectionInfo&) override {" << endl << indent() - << " return iface_.get();" << endl << indent() << "}" << endl << indent() - << "virtual void releaseHandler(" << base_if_name << "* /* handler */) override {}" << endl; + << "const ::apache::thrift::TConnectionInfo&) override {" << '\n' << indent() + << " return iface_.get();" << '\n' << indent() << "}" << '\n' << indent() + << "virtual void releaseHandler(" << base_if_name << "* /* handler */) override {}" << '\n'; - f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr<" << service_if_name - << "> iface_;" << endl; + f_header_ << '\n' << " protected:" << '\n' << indent() << "::std::shared_ptr<" << service_if_name + << "> iface_;" << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; } /** @@ -2151,14 +2239,14 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { extends = " , virtual public " + type_name(tservice->get_extends()) + style + "Null"; } f_header_ << "class " << service_name_ << style << "Null : virtual public " << service_name_ - << style << "If" << extends << " {" << endl << " public:" << endl; + << style << "If" << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "virtual ~" << service_name_ << style << "Null() {}" << endl; + f_header_ << indent() << "virtual ~" << service_name_ << style << "Null() {}" << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_header_ << indent() << function_signature(*f_iter, style, "", false) - << " override {" << endl; + << " override {" << '\n'; indent_up(); t_type* returntype = (*f_iter)->get_returntype(); @@ -2166,18 +2254,18 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { if (style == "") { if (returntype->is_void() || is_complex_type(returntype)) { - f_header_ << indent() << "return;" << endl; + f_header_ << indent() << "return;" << '\n'; } else { - f_header_ << indent() << declare_field(&returnfield, true) << endl << indent() - << "return _return;" << endl; + f_header_ << indent() << declare_field(&returnfield, true) << '\n' << indent() + << "return _return;" << '\n'; } } else if (style == "CobSv") { if (returntype->is_void()) { - f_header_ << indent() << "return cob();" << endl; + f_header_ << indent() << "return cob();" << '\n'; } else { t_field returnfield(returntype, "_return"); - f_header_ << indent() << declare_field(&returnfield, true) << endl << indent() - << "return cob(_return);" << endl; + f_header_ << indent() << declare_field(&returnfield, true) << '\n' << indent() + << "return cob(_return);" << '\n'; } } else { @@ -2185,10 +2273,10 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { } indent_down(); - f_header_ << indent() << "}" << endl; + f_header_ << indent() << "}" << '\n'; } indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; } void t_cpp_generator::generate_function_call(ostream& out, @@ -2219,7 +2307,7 @@ void t_cpp_generator::generate_function_call(ostream& out, } out << arg_prefix << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; } void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { @@ -2233,58 +2321,58 @@ void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { ofstream_with_content_based_conditional_update f_skeleton; f_skeleton.open(f_skeleton_name.c_str()); f_skeleton << "// This autogenerated skeleton file illustrates one way to adapt a synchronous" - << endl << "// interface into an asynchronous interface. You should copy it to another" - << endl + << '\n' << "// interface into an asynchronous interface. You should copy it to another" + << '\n' << "// filename to avoid overwriting it and rewrite as asynchronous any functions" - << endl << "// that would otherwise introduce unwanted latency." << endl << endl - << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl << endl - << "using namespace ::apache::thrift;" << endl - << "using namespace ::apache::thrift::protocol;" << endl - << "using namespace ::apache::thrift::transport;" << endl - << "using namespace ::apache::thrift::async;" << endl << endl; + << '\n' << "// that would otherwise introduce unwanted latency." << '\n' << '\n' + << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' << '\n' + << "using namespace ::apache::thrift;" << '\n' + << "using namespace ::apache::thrift::protocol;" << '\n' + << "using namespace ::apache::thrift::transport;" << '\n' + << "using namespace ::apache::thrift::async;" << '\n' << '\n'; // the following code would not compile: // using namespace ; // using namespace ::; if ((!ns.empty()) && (ns.compare(" ::") != 0)) { - f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << endl << endl; + f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << '\n' << '\n'; } - f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << endl - << " public:" << endl; + f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << '\n' + << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "Handler() {" << endl << indent() - << " // Your initialization goes here" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << svcname << "Handler() {" << '\n' << indent() + << " // Your initialization goes here" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_skeleton, *f_iter); - f_skeleton << indent() << function_signature(*f_iter, "") << " {" << endl << indent() - << " // Your implementation goes here" << endl << indent() << " printf(\"" - << (*f_iter)->get_name() << "\\n\");" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << function_signature(*f_iter, "") << " {" << '\n' << indent() + << " // Your implementation goes here" << '\n' << indent() << " printf(\"" + << (*f_iter)->get_name() << "\\n\");" << '\n' << indent() << "}" << '\n' << '\n'; } indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; f_skeleton << "class " << svcname << "AsyncHandler : " - << "public " << svcname << "CobSvIf {" << endl << " public:" << endl; + << "public " << svcname << "CobSvIf {" << '\n' << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "AsyncHandler() {" << endl << indent() + f_skeleton << indent() << svcname << "AsyncHandler() {" << '\n' << indent() << " syncHandler_ = std::unique_ptr<" << svcname << "Handler>(new " << svcname - << "Handler);" << endl << indent() << " // Your initialization goes here" << endl - << indent() << "}" << endl; - f_skeleton << indent() << "virtual ~" << service_name_ << "AsyncHandler();" << endl; + << "Handler);" << '\n' << indent() << " // Your initialization goes here" << '\n' + << indent() << "}" << '\n'; + f_skeleton << indent() << "virtual ~" << service_name_ << "AsyncHandler();" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_skeleton << endl << indent() << function_signature(*f_iter, "CobSv", "", true) << " {" - << endl; + f_skeleton << '\n' << indent() << function_signature(*f_iter, "CobSv", "", true) << " {" + << '\n'; indent_up(); t_type* returntype = (*f_iter)->get_returntype(); @@ -2292,32 +2380,32 @@ void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { string target = returntype->is_void() ? "" : "_return"; if (!returntype->is_void()) { - f_skeleton << indent() << declare_field(&returnfield, true) << endl; + f_skeleton << indent() << declare_field(&returnfield, true) << '\n'; } generate_function_call(f_skeleton, *f_iter, target, "syncHandler_", ""); - f_skeleton << indent() << "return cob(" << target << ");" << endl; + f_skeleton << indent() << "return cob(" << target << ");" << '\n'; scope_down(f_skeleton); } - f_skeleton << endl << " protected:" << endl << indent() << "std::unique_ptr<" << svcname - << "Handler> syncHandler_;" << endl; + f_skeleton << '\n' << " protected:" << '\n' << indent() << "std::unique_ptr<" << svcname + << "Handler> syncHandler_;" << '\n'; indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; - f_skeleton << indent() << "int main(int argc, char **argv) {" << endl; + f_skeleton << indent() << "int main(int argc, char **argv) {" << '\n'; indent_up(); f_skeleton - << indent() << "int port = 9090;" << endl << indent() << "::std::shared_ptr<" << svcname - << "AsyncHandler> handler(new " << svcname << "AsyncHandler());" << endl << indent() - << "::std::shared_ptr<" << svcname << "AsyncProcessor> processor(new " << svcname << "AsyncProcessor(handler));" << endl + << indent() << "int port = 9090;" << '\n' << indent() << "::std::shared_ptr<" << svcname + << "AsyncHandler> handler(new " << svcname << "AsyncHandler());" << '\n' << indent() + << "::std::shared_ptr<" << svcname << "AsyncProcessor> processor(new " << svcname << "AsyncProcessor(handler));" << '\n' << indent() << "::std::shared_ptr protocolFactory(new TBinaryProtocolFactory());" - << endl + << '\n' << indent() << "::std::shared_ptr protocolProcessor(new TAsyncProtocolProcessor(processor, protocolFactory));" - << endl << endl << indent() + << '\n' << '\n' << indent() << "TEvhttpServer server(protocolProcessor, port);" - << endl << indent() << "server.serve();" << endl << indent() << "return 0;" << endl; + << '\n' << indent() << "server.serve();" << '\n' << indent() << "return 0;" << '\n'; indent_down(); - f_skeleton << "}" << endl << endl; + f_skeleton << "}" << '\n' << '\n'; } /** @@ -2343,35 +2431,35 @@ void t_cpp_generator::generate_service_multiface(t_service* tservice) { // Generate the header portion f_header_ << "class " << service_name_ << "Multiface : " - << "virtual public " << service_name_ << "If" << extends_multiface << " {" << endl - << " public:" << endl; + << "virtual public " << service_name_ << "If" << extends_multiface << " {" << '\n' + << " public:" << '\n'; indent_up(); f_header_ << indent() << service_name_ << "Multiface(" << list_type - << "& ifaces) : ifaces_(ifaces) {" << endl; + << "& ifaces) : ifaces_(ifaces) {" << '\n'; if (!extends.empty()) { f_header_ << indent() << " std::vector >::iterator iter;" - << endl << indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {" - << endl << indent() << " " << extends << "Multiface::add(*iter);" << endl - << indent() << " }" << endl; + << '\n' << indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {" + << '\n' << indent() << " " << extends << "Multiface::add(*iter);" << '\n' + << indent() << " }" << '\n'; } - f_header_ << indent() << "}" << endl << indent() << "virtual ~" << service_name_ - << "Multiface() {}" << endl; + f_header_ << indent() << "}" << '\n' << indent() << "virtual ~" << service_name_ + << "Multiface() {}" << '\n'; indent_down(); // Protected data members - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); - f_header_ << indent() << list_type << " ifaces_;" << endl << indent() << service_name_ - << "Multiface() {}" << endl << indent() << "void add(::std::shared_ptr<" - << service_name_ << "If> iface) {" << endl; + f_header_ << indent() << list_type << " ifaces_;" << '\n' << indent() << service_name_ + << "Multiface() {}" << '\n' << indent() << "void add(::std::shared_ptr<" + << service_name_ << "If> iface) {" << '\n'; if (!extends.empty()) { - f_header_ << indent() << " " << extends << "Multiface::add(iface);" << endl; + f_header_ << indent() << " " << extends << "Multiface::add(iface);" << '\n'; } - f_header_ << indent() << " ifaces_.push_back(iface);" << endl << indent() << "}" << endl; + f_header_ << indent() << " ifaces_.push_back(iface);" << '\n' << indent() << "}" << '\n'; indent_down(); - f_header_ << indent() << " public:" << endl; + f_header_ << indent() << " public:" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2396,31 +2484,31 @@ void t_cpp_generator::generate_service_multiface(t_service* tservice) { } call += ")"; - f_header_ << indent() << function_signature(*f_iter, "") << " override {" << endl; + f_header_ << indent() << function_signature(*f_iter, "") << " override {" << '\n'; indent_up(); - f_header_ << indent() << "size_t sz = ifaces_.size();" << endl << indent() << "size_t i = 0;" - << endl << indent() << "for (; i < (sz - 1); ++i) {" << endl; + f_header_ << indent() << "size_t sz = ifaces_.size();" << '\n' << indent() << "size_t i = 0;" + << '\n' << indent() << "for (; i < (sz - 1); ++i) {" << '\n'; indent_up(); - f_header_ << indent() << call << ";" << endl; + f_header_ << indent() << call << ";" << '\n'; indent_down(); - f_header_ << indent() << "}" << endl; + f_header_ << indent() << "}" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { - f_header_ << indent() << call << ";" << endl << indent() << "return;" << endl; + f_header_ << indent() << call << ";" << '\n' << indent() << "return;" << '\n'; } else { - f_header_ << indent() << "return " << call << ";" << endl; + f_header_ << indent() << "return " << call << ";" << '\n'; } } else { - f_header_ << indent() << call << ";" << endl; + f_header_ << indent() << call << ";" << '\n'; } indent_down(); - f_header_ << indent() << "}" << endl << endl; + f_header_ << indent() << "}" << '\n' << '\n'; } indent_down(); - f_header_ << indent() << "};" << endl << endl; + f_header_ << indent() << "};" << '\n' << '\n'; } /** @@ -2471,7 +2559,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) f_header_ << template_header << "class " << service_name_ << style << "Client" << short_suffix << " : " << "virtual public " << service_name_ << ifstyle << if_suffix << extends_client << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); if (style != "Cob") { @@ -2484,18 +2572,18 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (extends.empty()) { if (style == "Concurrent") { - f_header_ << ": sync_(sync)" << endl; + f_header_ << ": sync_(sync)" << '\n'; } - f_header_ << "{" << endl; - f_header_ << indent() << " setProtocol" << short_suffix << "(prot);" << endl << indent() - << "}" << endl; + f_header_ << "{" << '\n'; + f_header_ << indent() << " setProtocol" << short_suffix << "(prot);" << '\n' << indent() + << "}" << '\n'; } else { - f_header_ << ":" << endl; + f_header_ << ":" << '\n'; f_header_ << indent() << " " << extends << style << client_suffix << "(prot, prot"; if (style == "Concurrent") { f_header_ << ", sync"; } - f_header_ << ") {}" << endl; + f_header_ << ") {}" << '\n'; } f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr @@ -2504,41 +2592,41 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync"; } f_header_ << ") "; - + if (extends.empty()) { if (style == "Concurrent") { - f_header_ << ": sync_(sync)" << endl; + f_header_ << ": sync_(sync)" << '\n'; } - f_header_ << "{" << endl; - f_header_ << indent() << " setProtocol" << short_suffix << "(iprot,oprot);" << endl - << indent() << "}" << endl; + f_header_ << "{" << '\n'; + f_header_ << indent() << " setProtocol" << short_suffix << "(iprot,oprot);" << '\n' + << indent() << "}" << '\n'; } else { f_header_ << ":" << indent() << " " << extends << style << client_suffix << "(iprot, oprot"; if (style == "Concurrent") { f_header_ << ", sync"; } - f_header_ << ") {}" << endl; + f_header_ << ") {}" << '\n'; } // create the setProtocol methods if (extends.empty()) { - f_header_ << " private:" << endl; + f_header_ << " private:" << '\n'; // 1: one parameter f_header_ << indent() << "void setProtocol" << short_suffix << "(" << prot_ptr << " prot) {" - << endl; - f_header_ << indent() << "setProtocol" << short_suffix << "(prot,prot);" << endl; - f_header_ << indent() << "}" << endl; + << '\n'; + f_header_ << indent() << "setProtocol" << short_suffix << "(prot,prot);" << '\n'; + f_header_ << indent() << "}" << '\n'; // 2: two parameter f_header_ << indent() << "void setProtocol" << short_suffix << "(" << prot_ptr << " iprot, " - << prot_ptr << " oprot) {" << endl; + << prot_ptr << " oprot) {" << '\n'; - f_header_ << indent() << " piprot_=iprot;" << endl << indent() << " poprot_=oprot;" << endl - << indent() << " iprot_ = iprot.get();" << endl << indent() - << " oprot_ = oprot.get();" << endl; + f_header_ << indent() << " piprot_=iprot;" << '\n' << indent() << " poprot_=oprot;" << '\n' + << indent() << " iprot_ = iprot.get();" << '\n' << indent() + << " oprot_ = oprot.get();" << '\n'; - f_header_ << indent() << "}" << endl; - f_header_ << " public:" << endl; + f_header_ << indent() << "}" << '\n'; + f_header_ << " public:" << '\n'; } // Generate getters for the protocols. @@ -2546,45 +2634,45 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) // TODO(simpkins): should they be templated? f_header_ << indent() << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {" - << endl << indent() << " return " << _this << "piprot_;" << endl << indent() << "}" - << endl; + << '\n' << indent() << " return " << _this << "piprot_;" << '\n' << indent() << "}" + << '\n'; f_header_ << indent() << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {" - << endl << indent() << " return " << _this << "poprot_;" << endl << indent() << "}" - << endl; + << '\n' << indent() << " return " << _this << "poprot_;" << '\n' << indent() << "}" + << '\n'; } else /* if (style == "Cob") */ { f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << "std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel, " - << "::apache::thrift::protocol::TProtocolFactory* protocolFactory) :" << endl; + << "::apache::thrift::protocol::TProtocolFactory* protocolFactory) :" << '\n'; if (extends.empty()) { - f_header_ << indent() << " channel_(channel)," << endl << indent() - << " itrans_(new ::apache::thrift::transport::TMemoryBuffer())," << endl + f_header_ << indent() << " channel_(channel)," << '\n' << indent() + << " itrans_(new ::apache::thrift::transport::TMemoryBuffer())," << '\n' << indent() << " otrans_(new ::apache::thrift::transport::TMemoryBuffer())," - << endl; + << '\n'; if (gen_templates_) { // TProtocolFactory classes return generic TProtocol pointers. // We have to dynamic cast to the Protocol_ type we are expecting. f_header_ << indent() << " piprot_(::std::dynamic_pointer_cast(" - << "protocolFactory->getProtocol(itrans_)))," << endl << indent() + << "protocolFactory->getProtocol(itrans_)))," << '\n' << indent() << " poprot_(::std::dynamic_pointer_cast(" - << "protocolFactory->getProtocol(otrans_))) {" << endl; + << "protocolFactory->getProtocol(otrans_))) {" << '\n'; // Throw a TException if either dynamic cast failed. - f_header_ << indent() << " if (!piprot_ || !poprot_) {" << endl << indent() + f_header_ << indent() << " if (!piprot_ || !poprot_) {" << '\n' << indent() << " throw ::apache::thrift::TException(\"" << "TProtocolFactory returned unexpected protocol type in " << service_name_ - << style << "Client" << short_suffix << " constructor\");" << endl << indent() - << " }" << endl; + << style << "Client" << short_suffix << " constructor\");" << '\n' << indent() + << " }" << '\n'; } else { - f_header_ << indent() << " piprot_(protocolFactory->getProtocol(itrans_))," << endl - << indent() << " poprot_(protocolFactory->getProtocol(otrans_)) {" << endl; + f_header_ << indent() << " piprot_(protocolFactory->getProtocol(itrans_))," << '\n' + << indent() << " poprot_(protocolFactory->getProtocol(otrans_)) {" << '\n'; } - f_header_ << indent() << " iprot_ = piprot_.get();" << endl << indent() - << " oprot_ = poprot_.get();" << endl << indent() << "}" << endl; + f_header_ << indent() << " iprot_ = piprot_.get();" << '\n' << indent() + << " oprot_ = poprot_.get();" << '\n' << indent() << "}" << '\n'; } else { f_header_ << indent() << " " << extends << style << client_suffix - << "(channel, protocolFactory) {}" << endl; + << "(channel, protocolFactory) {}" << '\n'; } } @@ -2592,10 +2680,10 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) generate_java_doc(f_header_, tservice); f_header_ << indent() - << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << endl - << indent() << " return " << _this << "channel_;" << endl << indent() << "}" << endl; + << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << '\n' + << indent() << " return " << _this << "channel_;" << '\n' << indent() << "}" << '\n'; if (!gen_no_client_completion_) { - f_header_ << indent() << "virtual void completed__(bool /* success */) {}" << endl; + f_header_ << indent() << "virtual void completed__(bool /* success */) {}" << '\n'; } } @@ -2603,8 +2691,8 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) vector::const_iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_header_, *f_iter); - indent(f_header_) << function_signature(*f_iter, ifstyle) - << " override;" << endl; + indent(f_header_) << function_signature(*f_iter, ifstyle) + << " override;" << '\n'; // TODO(dreiss): Use private inheritance to avoid generating thise in cob-style. if (style == "Concurrent" && !(*f_iter)->is_oneway()) { // concurrent clients need to move the seqid from the send function to the @@ -2613,12 +2701,12 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) t_function send_function(g_type_i32, /*returning seqid*/ string("send_") + (*f_iter)->get_name(), (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function, "") << ";" << endl; + indent(f_header_) << function_signature(&send_function, "") << ";" << '\n'; } else { t_function send_function(g_type_void, string("send_") + (*f_iter)->get_name(), (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function, "") << ";" << endl; + indent(f_header_) << function_signature(&send_function, "") << ";" << '\n'; } if (!(*f_iter)->is_oneway()) { if (style == "Concurrent") { @@ -2628,52 +2716,52 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &seqIdArgStruct); - indent(f_header_) << function_signature(&recv_function, "") << ";" << endl; + indent(f_header_) << function_signature(&recv_function, "") << ";" << '\n'; } else { t_struct noargs(program_); t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &noargs); - indent(f_header_) << function_signature(&recv_function, "") << ";" << endl; + indent(f_header_) << function_signature(&recv_function, "") << ";" << '\n'; } } } indent_down(); if (extends.empty()) { - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); if (style == "Cob") { f_header_ << indent() - << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << endl + << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << '\n' << indent() - << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << endl + << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> otrans_;" - << endl; + << '\n'; } f_header_ << - indent() << prot_ptr << " piprot_;" << endl << - indent() << prot_ptr << " poprot_;" << endl << - indent() << protocol_type << "* iprot_;" << endl << - indent() << protocol_type << "* oprot_;" << endl; + indent() << prot_ptr << " piprot_;" << '\n' << + indent() << prot_ptr << " poprot_;" << '\n' << + indent() << protocol_type << "* iprot_;" << '\n' << + indent() << protocol_type << "* oprot_;" << '\n'; if (style == "Concurrent") { f_header_ << - indent() << "std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync_;"< sync_;" << '\n'; } indent_down(); } - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (gen_templates_) { // Output a backwards compatibility typedef using // TProtocol as the template parameter. f_header_ << "typedef " << service_name_ << style << "ClientT< ::apache::thrift::protocol::TProtocol> " << service_name_ << style - << "Client;" << endl << endl; + << "Client;" << '\n' << '\n'; } string scope = service_name_ + style + client_suffix + "::"; @@ -2695,7 +2783,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(*f_iter, ifstyle, scope) << endl; + indent(out) << function_signature(*f_iter, ifstyle, scope) << '\n'; scope_up(out); indent(out) << seqIdCapture << "send_" << funname << "("; @@ -2714,33 +2802,33 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) } out << (*fld_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; if (style != "Cob") { if (!(*f_iter)->is_oneway()) { out << indent(); if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { - out << "recv_" << funname << "(_return" << seqIdCommaUse << ");" << endl; + out << "recv_" << funname << "(_return" << seqIdCommaUse << ");" << '\n'; } else { - out << "return recv_" << funname << "(" << seqIdUse << ");" << endl; + out << "return recv_" << funname << "(" << seqIdUse << ");" << '\n'; } } else { - out << "recv_" << funname << "(" << seqIdUse << ");" << endl; + out << "recv_" << funname << "(" << seqIdUse << ");" << '\n'; } } } else { if (!(*f_iter)->is_oneway()) { out << indent() << _this << "channel_->sendAndRecvMessage(" << "::std::bind(cob, this), " << _this << "otrans_.get(), " << _this << "itrans_.get());" - << endl; + << '\n'; } else { out << indent() << _this << "channel_->sendMessage(" - << "::std::bind(cob, this), " << _this << "otrans_.get());" << endl; + << "::std::bind(cob, this), " << _this << "otrans_.get());" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; // if (style != "Cob") // TODO(dreiss): Libify the client and don't generate this for cob-style if (true) { @@ -2757,7 +2845,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(&send_function, "", scope) << endl; + indent(out) << function_signature(&send_function, "", scope) << '\n'; scope_up(out); // Function arguments and results @@ -2772,41 +2860,41 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) } // Serialize the request out << - indent() << "int32_t cseqid = " << cseqidVal << ";" << endl; + indent() << "int32_t cseqid = " << cseqidVal << ";" << '\n'; if(style == "Concurrent") { out << - indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());" << endl; + indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());" << '\n'; } if (style == "Cob") { out << - indent() << _this << "otrans_->resetBuffer();" << endl; + indent() << _this << "otrans_->resetBuffer();" << '\n'; } out << indent() << _this << "oprot_->writeMessageBegin(\"" << (*f_iter)->get_name() << "\", ::apache::thrift::protocol::" << ((*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL") << - ", cseqid);" << endl << endl << - indent() << argsname << " args;" << endl; + ", cseqid);" << '\n' << '\n' << + indent() << argsname << " args;" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { out << indent() << "args." << (*fld_iter)->get_name() << " = &" << (*fld_iter)->get_name() - << ";" << endl; + << ";" << '\n'; } - out << indent() << "args.write(" << _this << "oprot_);" << endl << endl << indent() << _this - << "oprot_->writeMessageEnd();" << endl << indent() << _this - << "oprot_->getTransport()->writeEnd();" << endl << indent() << _this - << "oprot_->getTransport()->flush();" << endl; + out << indent() << "args.write(" << _this << "oprot_);" << '\n' << '\n' << indent() << _this + << "oprot_->writeMessageEnd();" << '\n' << indent() << _this + << "oprot_->getTransport()->writeEnd();" << '\n' << indent() << _this + << "oprot_->getTransport()->flush();" << '\n'; if (style == "Concurrent") { - out << endl << indent() << "sentry.commit();" << endl; + out << '\n' << indent() << "sentry.commit();" << '\n'; if (!(*f_iter)->is_oneway()) { - out << indent() << "return cseqid;" << endl; + out << indent() << "return cseqid;" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; // Generate recv function only if not an oneway function if (!(*f_iter)->is_oneway()) { @@ -2828,124 +2916,123 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(&recv_function, "", scope) << endl; + indent(out) << function_signature(&recv_function, "", scope) << '\n'; scope_up(out); - out << endl << - indent() << "int32_t rseqid = 0;" << endl << - indent() << "std::string fname;" << endl << - indent() << "::apache::thrift::protocol::TMessageType mtype;" << endl; + out << '\n' << + indent() << "int32_t rseqid = 0;" << '\n' << + indent() << "std::string fname;" << '\n' << + indent() << "::apache::thrift::protocol::TMessageType mtype;" << '\n'; if(style == "Concurrent") { - out << - endl << - indent() << "// the read mutex gets dropped and reacquired as part of waitForWork()" << endl << - indent() << "// The destructor of this sentry wakes up other clients" << endl << - indent() << "::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);" << endl; + out << '\n' << + indent() << "// the read mutex gets dropped and reacquired as part of waitForWork()" << '\n' << + indent() << "// The destructor of this sentry wakes up other clients" << '\n' << + indent() << "::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);" << '\n'; } if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "bool completed = false;" << endl << endl << indent() << "try {"; + out << indent() << "bool completed = false;" << '\n' << '\n' << indent() << "try {"; indent_up(); } - out << endl; + out << '\n'; if (style == "Concurrent") { out << - indent() << "while(true) {" << endl << - indent() << " if(!this->sync_->getPending(fname, mtype, rseqid)) {" << endl; + indent() << "while(true) {" << '\n' << + indent() << " if(!this->sync_->getPending(fname, mtype, rseqid)) {" << '\n'; indent_up(); indent_up(); } out << - indent() << _this << "iprot_->readMessageBegin(fname, mtype, rseqid);" << endl; + indent() << _this << "iprot_->readMessageBegin(fname, mtype, rseqid);" << '\n'; if (style == "Concurrent") { scope_down(out); - out << indent() << "if(seqid == rseqid) {" << endl; + out << indent() << "if(seqid == rseqid) {" << '\n'; indent_up(); } out << - indent() << "if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {" << endl << - indent() << " ::apache::thrift::TApplicationException x;" << endl << - indent() << " x.read(" << _this << "iprot_);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << "if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {" << '\n' << + indent() << " ::apache::thrift::TApplicationException x;" << '\n' << + indent() << " x.read(" << _this << "iprot_);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } out << - indent() << " throw x;" << endl << - indent() << "}" << endl << - indent() << "if (mtype != ::apache::thrift::protocol::T_REPLY) {" << endl << - indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << " throw x;" << '\n' << + indent() << "}" << '\n' << + indent() << "if (mtype != ::apache::thrift::protocol::T_REPLY) {" << '\n' << + indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(false);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(false);" + << '\n'; } out << - indent() << "}" << endl << - indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << endl << - indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << "}" << '\n' << + indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << '\n' << + indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(false);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(false);" + << '\n'; } if (style == "Concurrent") { - out << endl << - indent() << " // in a bad state, don't commit" << endl << - indent() << " using ::apache::thrift::protocol::TProtocolException;" << endl << - indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + out << '\n' << + indent() << " // in a bad state, don't commit" << '\n' << + indent() << " using ::apache::thrift::protocol::TProtocolException;" << '\n' << + indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (!(*f_iter)->get_returntype()->is_void() && !is_complex_type((*f_iter)->get_returntype())) { t_field returnfield((*f_iter)->get_returntype(), "_return"); - out << indent() << declare_field(&returnfield) << endl; + out << indent() << declare_field(&returnfield) << '\n'; } - out << indent() << resultname << " result;" << endl; + out << indent() << resultname << " result;" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { - out << indent() << "result.success = &_return;" << endl; + out << indent() << "result.success = &_return;" << '\n'; } - out << indent() << "result.read(" << _this << "iprot_);" << endl << indent() << _this - << "iprot_->readMessageEnd();" << endl << indent() << _this - << "iprot_->getTransport()->readEnd();" << endl << endl; + out << indent() << "result.read(" << _this << "iprot_);" << '\n' << indent() << _this + << "iprot_->readMessageEnd();" << '\n' << indent() << _this + << "iprot_->getTransport()->readEnd();" << '\n' << '\n'; // Careful, only look for _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { out << - indent() << "if (result.__isset.success) {" << endl; + indent() << "if (result.__isset.success) {" << '\n'; out << - indent() << " // _return pointer has now been filled" << endl; + indent() << " // _return pointer has now been filled" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } out << - indent() << " return;" << endl << - indent() << "}" << endl; + indent() << " return;" << '\n' << + indent() << "}" << '\n'; } else { - out << indent() << "if (result.__isset.success) {" << endl; + out << indent() << "if (result.__isset.success) {" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } - out << indent() << " return _return;" << endl << indent() << "}" << endl; + out << indent() << " return _return;" << '\n' << indent() << "}" << '\n'; } } @@ -2953,62 +3040,62 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl; + out << indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } - out << indent() << " throw result." << (*x_iter)->get_name() << ";" << endl << indent() - << "}" << endl; + out << indent() << " throw result." << (*x_iter)->get_name() << ";" << '\n' << indent() + << "}" << '\n'; } // We only get here if we are a void function if ((*f_iter)->get_returntype()->is_void()) { if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "completed = true;" << endl << indent() << "completed__(true);" - << endl; + out << indent() << "completed = true;" << '\n' << indent() << "completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << "sentry.commit();" << endl; + out << indent() << "sentry.commit();" << '\n'; } - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; } else { if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "completed = true;" << endl << indent() << "completed__(true);" - << endl; + out << indent() << "completed = true;" << '\n' << indent() << "completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << "// in a bad state, don't commit" << endl; + out << indent() << "// in a bad state, don't commit" << '\n'; } out << indent() << "throw " "::apache::thrift::TApplicationException(::apache::thrift::" "TApplicationException::MISSING_RESULT, \"" << (*f_iter)->get_name() - << " failed: unknown result\");" << endl; + << " failed: unknown result\");" << '\n'; } if (style == "Concurrent") { indent_down(); indent_down(); - out << - indent() << " }" << endl << - indent() << " // seqid != rseqid" << endl << - indent() << " this->sync_->updatePending(fname, mtype, rseqid);" << endl << - endl << - indent() << " // this will temporarily unlock the readMutex, and let other clients get work done" << endl << - indent() << " this->sync_->waitForWork(seqid);" << endl << - indent() << "} // end while(true)" << endl; + out << indent() << " }" << '\n' + << indent() << " // seqid != rseqid" << '\n' + << indent() << " this->sync_->updatePending(fname, mtype, rseqid);" << '\n' + << '\n' + << indent() + << " // this will temporarily unlock the readMutex, and let other clients get work done" << '\n' + << indent() << " this->sync_->waitForWork(seqid);" << '\n' + << indent() << "} // end while(true)" << '\n'; } if (style == "Cob" && !gen_no_client_completion_) { indent_down(); - out << indent() << "} catch (...) {" << endl << indent() << " if (!completed) {" << endl - << indent() << " completed__(false);" << endl << indent() << " }" << endl - << indent() << " throw;" << endl << indent() << "}" << endl; + out << indent() << "} catch (...) {" << '\n' << indent() << " if (!completed) {" << '\n' + << indent() << " completed__(false);" << '\n' << indent() << " }" << '\n' + << indent() << " throw;" << '\n' << indent() << "}" << '\n'; } // Close function scope_down(out); - out << endl; + out << '\n'; } } } @@ -3144,61 +3231,61 @@ void ProcessorGenerator::generate_class_definition() { // Generate the header portion f_header_ << template_header_ << "class " << class_name_ << " : public " << parent_class << " {" - << endl; + << '\n'; // Protected data members - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); - f_header_ << indent() << "::std::shared_ptr<" << if_name_ << "> iface_;" << endl; + f_header_ << indent() << "::std::shared_ptr<" << if_name_ << "> iface_;" << '\n'; f_header_ << indent() << "virtual " << ret_type_ << "dispatchCall(" << finish_cob_ << "::apache::thrift::protocol::TProtocol* iprot, " << "::apache::thrift::protocol::TProtocol* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ - << ") override;" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ + << ") override;" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "virtual " << ret_type_ << "dispatchCallTemplated(" << finish_cob_ << "Protocol_* iprot, Protocol_* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ << ");" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ << ");" << '\n'; } indent_down(); // Process function declarations - f_header_ << " private:" << endl; + f_header_ << " private:" << '\n'; indent_up(); // Declare processMap_ f_header_ << indent() << "typedef void (" << class_name_ << "::*" << "ProcessFunction)(" << finish_cob_decl_ << "int32_t, " << "::apache::thrift::protocol::TProtocol*, " - << "::apache::thrift::protocol::TProtocol*" << call_context_decl_ << ");" << endl; + << "::apache::thrift::protocol::TProtocol*" << call_context_decl_ << ");" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "typedef void (" << class_name_ << "::*" << "SpecializedProcessFunction)(" << finish_cob_decl_ << "int32_t, " - << "Protocol_*, Protocol_*" << call_context_decl_ << ");" << endl << indent() - << "struct ProcessFunctions {" << endl << indent() << " ProcessFunction generic;" - << endl << indent() << " SpecializedProcessFunction specialized;" << endl << indent() + << "Protocol_*, Protocol_*" << call_context_decl_ << ");" << '\n' << indent() + << "struct ProcessFunctions {" << '\n' << indent() << " ProcessFunction generic;" + << '\n' << indent() << " SpecializedProcessFunction specialized;" << '\n' << indent() << " ProcessFunctions(ProcessFunction g, " - << "SpecializedProcessFunction s) :" << endl << indent() << " generic(g)," << endl - << indent() << " specialized(s) {}" << endl << indent() + << "SpecializedProcessFunction s) :" << '\n' << indent() << " generic(g)," << '\n' + << indent() << " specialized(s) {}" << '\n' << indent() << " ProcessFunctions() : generic(nullptr), specialized(nullptr) " - << "{}" << endl << indent() << "};" << endl << indent() + << "{}" << '\n' << indent() << "};" << '\n' << indent() << "typedef std::map " - << "ProcessMap;" << endl; + << "ProcessMap;" << '\n'; } else { f_header_ << indent() << "typedef std::map " - << "ProcessMap;" << endl; + << "ProcessMap;" << '\n'; } - f_header_ << indent() << "ProcessMap processMap_;" << endl; + f_header_ << indent() << "ProcessMap processMap_;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_header_) << "void process_" << (*f_iter)->get_name() << "(" << finish_cob_ << "int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, " "::apache::thrift::protocol::TProtocol* oprot" << call_context_ << ");" - << endl; + << '\n'; if (generator_->gen_templates_) { indent(f_header_) << "void process_" << (*f_iter)->get_name() << "(" << finish_cob_ << "int32_t seqid, Protocol_* iprot, Protocol_* oprot" << call_context_ - << ");" << endl; + << ");" << '\n'; } if (style_ == "Cob") { // XXX Factor this out, even if it is a pain. @@ -3208,56 +3295,56 @@ void ProcessorGenerator::generate_class_definition() { f_header_ << indent() << "void return_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "::apache::thrift::protocol::TProtocol* oprot, " - << "void* ctx" << ret_arg << ");" << endl; + << "void* ctx" << ret_arg << ");" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "void return_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " - << "Protocol_* oprot, void* ctx" << ret_arg << ");" << endl; + << "Protocol_* oprot, void* ctx" << ret_arg << ");" << '\n'; } // XXX Don't declare throw if it doesn't exist f_header_ << indent() << "void throw_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "::apache::thrift::protocol::TProtocol* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw);" << endl; + << "::apache::thrift::TDelayedException* _throw);" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "void throw_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "Protocol_* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw);" << endl; + << "::apache::thrift::TDelayedException* _throw);" << '\n'; } } } - f_header_ << " public:" << endl << indent() << class_name_ << "(::std::shared_ptr<" << if_name_ - << "> iface) :" << endl; + f_header_ << " public:" << '\n' << indent() << class_name_ << "(::std::shared_ptr<" << if_name_ + << "> iface) :" << '\n'; if (!extends_.empty()) { - f_header_ << indent() << " " << extends_ << "(iface)," << endl; + f_header_ << indent() << " " << extends_ << "(iface)," << '\n'; } - f_header_ << indent() << " iface_(iface) {" << endl; + f_header_ << indent() << " iface_(iface) {" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_header_ << indent() << "processMap_[\"" << (*f_iter)->get_name() << "\"] = "; if (generator_->gen_templates_) { - f_header_ << "ProcessFunctions(" << endl; + f_header_ << "ProcessFunctions(" << '\n'; if (generator_->gen_templates_only_) { - indent(f_header_) << " nullptr," << endl; + indent(f_header_) << " nullptr," << '\n'; } else { indent(f_header_) << " &" << class_name_ << "::process_" << (*f_iter)->get_name() << "," - << endl; + << '\n'; } indent(f_header_) << " &" << class_name_ << "::process_" << (*f_iter)->get_name() << ")"; } else { f_header_ << "&" << class_name_ << "::process_" << (*f_iter)->get_name(); } - f_header_ << ";" << endl; + f_header_ << ";" << '\n'; } indent_down(); - f_header_ << indent() << "}" << endl << endl << indent() << "virtual ~" << class_name_ << "() {}" - << endl; + f_header_ << indent() << "}" << '\n' << '\n' << indent() << "virtual ~" << class_name_ << "() {}" + << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (generator_->gen_templates_) { // Generate a backwards compatible typedef, for callers who don't know @@ -3270,7 +3357,7 @@ void ProcessorGenerator::generate_class_definition() { // Therefore, we define TDummyProtocol solely so we can use it as the // template parameter here. f_header_ << "typedef " << class_name_ << "< ::apache::thrift::protocol::TDummyProtocol > " - << service_name_ << pstyle_ << "Processor;" << endl << endl; + << service_name_ << pstyle_ << "Processor;" << '\n' << '\n'; } } @@ -3292,32 +3379,32 @@ void ProcessorGenerator::generate_dispatch_call(bool template_protocol) { f_out_ << template_header_ << ret_type_ << class_name_ << template_suffix_ << "::dispatchCall" << function_suffix << "(" << finish_cob_ << protocol << "* iprot, " << protocol << "* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ << ") {" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ << ") {" << '\n'; indent_up(); // HOT: member function pointer map - f_out_ << indent() << typename_str_ << "ProcessMap::iterator pfn;" << endl << indent() - << "pfn = processMap_.find(fname);" << endl << indent() - << "if (pfn == processMap_.end()) {" << endl; + f_out_ << indent() << typename_str_ << "ProcessMap::iterator pfn;" << '\n' << indent() + << "pfn = processMap_.find(fname);" << '\n' << indent() + << "if (pfn == processMap_.end()) {" << '\n'; if (extends_.empty()) { - f_out_ << indent() << " iprot->skip(::apache::thrift::protocol::T_STRUCT);" << endl << indent() - << " iprot->readMessageEnd();" << endl << indent() - << " iprot->getTransport()->readEnd();" << endl << indent() + f_out_ << indent() << " iprot->skip(::apache::thrift::protocol::T_STRUCT);" << '\n' << indent() + << " iprot->readMessageEnd();" << '\n' << indent() + << " iprot->getTransport()->readEnd();" << '\n' << indent() << " ::apache::thrift::TApplicationException " "x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, \"Invalid method name: " - "'\"+fname+\"'\");" << endl << indent() + "'\"+fname+\"'\");" << '\n' << indent() << " oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);" - << endl << indent() << " x.write(oprot);" << endl << indent() - << " oprot->writeMessageEnd();" << endl << indent() - << " oprot->getTransport()->writeEnd();" << endl << indent() - << " oprot->getTransport()->flush();" << endl << indent() - << (style_ == "Cob" ? " return cob(true);" : " return true;") << endl; + << '\n' << indent() << " x.write(oprot);" << '\n' << indent() + << " oprot->writeMessageEnd();" << '\n' << indent() + << " oprot->getTransport()->writeEnd();" << '\n' << indent() + << " oprot->getTransport()->flush();" << '\n' << indent() + << (style_ == "Cob" ? " return cob(true);" : " return true;") << '\n'; } else { f_out_ << indent() << " return " << extends_ << "::dispatchCall(" << (style_ == "Cob" ? "cob, " : "") << "iprot, oprot, fname, seqid" << call_context_arg_ - << ");" << endl; + << ");" << '\n'; } - f_out_ << indent() << "}" << endl; + f_out_ << indent() << "}" << '\n'; if (template_protocol) { f_out_ << indent() << "(this->*(pfn->second.specialized))"; } else { @@ -3331,17 +3418,17 @@ void ProcessorGenerator::generate_dispatch_call(bool template_protocol) { f_out_ << indent() << "(this->*(pfn->second))"; } } - f_out_ << "(" << cob_arg_ << "seqid, iprot, oprot" << call_context_arg_ << ");" << endl; + f_out_ << "(" << cob_arg_ << "seqid, iprot, oprot" << call_context_arg_ << ");" << '\n'; // TODO(dreiss): return pfn ret? if (style_ == "Cob") { - f_out_ << indent() << "return;" << endl; + f_out_ << indent() << "return;" << '\n'; } else { - f_out_ << indent() << "return true;" << endl; + f_out_ << indent() << "return true;" << '\n'; } indent_down(); - f_out_ << "}" << endl << endl; + f_out_ << "}" << '\n' << '\n'; } void ProcessorGenerator::generate_process_functions() { @@ -3363,49 +3450,49 @@ void ProcessorGenerator::generate_factory() { // Generate the factory class definition f_header_ << template_header_ << "class " << factory_class_name_ << " : public ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessorFactory" : "TProcessorFactory") << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); f_header_ << indent() << factory_class_name_ << "(const ::std::shared_ptr< " << if_factory_name - << " >& handlerFactory) noexcept :" << endl << indent() - << " handlerFactory_(handlerFactory) {}" << endl << endl << indent() + << " >& handlerFactory) noexcept :" << '\n' << indent() + << " handlerFactory_(handlerFactory) {}" << '\n' << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > " << "getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) override;" - << endl; + << '\n'; - f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr< " - << if_factory_name << " > handlerFactory_;" << endl; + f_header_ << '\n' << " protected:" << '\n' << indent() << "::std::shared_ptr< " + << if_factory_name << " > handlerFactory_;" << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; // If we are generating templates, output a typedef for the plain // factory name. if (generator_->gen_templates_) { f_header_ << "typedef " << factory_class_name_ << "< ::apache::thrift::protocol::TDummyProtocol > " << service_name_ << pstyle_ - << "ProcessorFactory;" << endl << endl; + << "ProcessorFactory;" << '\n' << '\n'; } // Generate the getProcessor() method f_out_ << template_header_ << indent() << "::std::shared_ptr< ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > " << factory_class_name_ << template_suffix_ << "::getProcessor(" - << "const ::apache::thrift::TConnectionInfo& connInfo) {" << endl; + << "const ::apache::thrift::TConnectionInfo& connInfo) {" << '\n'; indent_up(); f_out_ << indent() << "::apache::thrift::ReleaseHandler< " << if_factory_name - << " > cleanup(handlerFactory_);" << endl << indent() << "::std::shared_ptr< " + << " > cleanup(handlerFactory_);" << '\n' << indent() << "::std::shared_ptr< " << if_name_ << " > handler(" - << "handlerFactory_->getHandler(connInfo), cleanup);" << endl << indent() + << "handlerFactory_->getHandler(connInfo), cleanup);" << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > " - << "processor(new " << class_name_ << template_suffix_ << "(handler));" << endl << indent() - << "return processor;" << endl; + << "processor(new " << class_name_ << template_suffix_ << "(handler));" << '\n' << indent() + << "return processor;" << '\n'; indent_down(); - f_out_ << indent() << "}" << endl << endl; + f_out_ << indent() << "}" << '\n' << '\n'; } /** @@ -3450,7 +3537,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult"); generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_); - generate_struct_definition(out, f_service_, &result, false); + generate_struct_definition(out, f_service_, &result, false, false, true); generate_struct_reader(out, &result, true); if (gen_cob_style_) { generate_struct_writer(out, &result, true); @@ -3487,45 +3574,45 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (style != "Cob") { // Open function if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } const bool unnamed_oprot_seqid = tfunction->is_oneway() && !(gen_templates_ && !specialized); out << "void " << tservice->get_name() << "Processor" << class_suffix << "::" << "process_" << tfunction->get_name() << "(" << "int32_t" << (unnamed_oprot_seqid ? ", " : " seqid, ") << prot_type << "* iprot, " << prot_type << "*" << (unnamed_oprot_seqid ? ", " : " oprot, ") << "void* callContext)" - << endl; + << '\n'; scope_up(out); string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args"; string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result"; if (tfunction->is_oneway() && !unnamed_oprot_seqid) { - out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + out << indent() << "(void) seqid;" << '\n' << indent() << "(void) oprot;" << '\n'; } - out << indent() << "void* ctx = nullptr;" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() + out << indent() << "void* ctx = nullptr;" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() << " ctx = this->eventHandler_->getContext(" << service_func_name << ", callContext);" - << endl << indent() << "}" << endl << indent() + << '\n' << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << endl << indent() << argsname << " args;" << endl << indent() - << "args.read(iprot);" << endl << indent() << "iprot->readMessageEnd();" << endl << indent() - << "uint32_t bytes = iprot->getTransport()->readEnd();" << endl << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << '\n' << indent() << argsname << " args;" << '\n' << indent() + << "args.read(iprot);" << '\n' << indent() << "iprot->readMessageEnd();" << '\n' << indent() + << "uint32_t bytes = iprot->getTransport()->readEnd();" << '\n' << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << '\n'; // Declare result if (!tfunction->is_oneway()) { - out << indent() << resultname << " result;" << endl; + out << indent() << resultname << " result;" << '\n'; } // Try block for functions with exceptions - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); // Generate the function call @@ -3549,11 +3636,11 @@ void t_cpp_generator::generate_process_function(t_service* tservice, } out << "args." << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { - out << indent() << "result.__isset.success = true;" << endl; + out << indent() << "result.__isset.success = true;" << '\n'; } indent_down(); @@ -3562,12 +3649,12 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << " catch (" << type_name((*x_iter)->get_type()) << " &" << (*x_iter)->get_name() - << ") {" << endl; + << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); out << indent() << "result." << (*x_iter)->get_name() - << " = std::move(" << (*x_iter)->get_name() << ");" << endl - << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << endl; + << " = std::move(" << (*x_iter)->get_name() << ");" << '\n' + << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << '\n'; indent_down(); out << indent() << "}"; } else { @@ -3577,53 +3664,53 @@ void t_cpp_generator::generate_process_function(t_service* tservice, } if (!tfunction->is_oneway()) { - out << " catch (const std::exception& e) {" << endl; + out << " catch (const std::exception& e) {" << '\n'; } else { - out << " catch (const std::exception&) {" << endl; + out << " catch (const std::exception&) {" << '\n'; } indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n'; if (!tfunction->is_oneway()) { - out << endl << indent() << "::apache::thrift::TApplicationException x(e.what());" << endl + out << '\n' << indent() << "::apache::thrift::TApplicationException x(e.what());" << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl; + << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n'; } - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "return;" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "return;" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; return; } // Serialize the result into a struct - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl << indent() - << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "bytes = oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() + << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' << indent() + << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "bytes = oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n' << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n'; // Close function scope_down(out); - out << endl; + out << '\n'; } // Cob style. @@ -3631,11 +3718,11 @@ void t_cpp_generator::generate_process_function(t_service* tservice, // Processor entry point. // TODO(edhall) update for callContext when TEventServer is ready if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::process_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " - << prot_type << "* iprot, " << prot_type << "* oprot)" << endl; + << prot_type << "* iprot, " << prot_type << "* oprot)" << '\n'; scope_up(out); // TODO(simpkins): we could try to consoldate this @@ -3643,55 +3730,55 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (gen_templates_ && !specialized) { // If these are instances of Protocol_, instead of any old TProtocol, // use the specialized process function instead. - out << indent() << "Protocol_* _iprot = dynamic_cast(iprot);" << endl << indent() - << "Protocol_* _oprot = dynamic_cast(oprot);" << endl << indent() - << "if (_iprot && _oprot) {" << endl << indent() << " return process_" - << tfunction->get_name() << "(cob, seqid, _iprot, _oprot);" << endl << indent() << "}" - << endl << indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << endl << indent() - << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl << endl; + out << indent() << "Protocol_* _iprot = dynamic_cast(iprot);" << '\n' << indent() + << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' << indent() + << "if (_iprot && _oprot) {" << '\n' << indent() << " return process_" + << tfunction->get_name() << "(cob, seqid, _iprot, _oprot);" << '\n' << indent() << "}" + << '\n' << indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << '\n' << indent() + << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << '\n' << '\n'; } if (tfunction->is_oneway()) { - out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + out << indent() << "(void) seqid;" << '\n' << indent() << "(void) oprot;" << '\n'; } - out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl - << indent() << "void* ctx = nullptr;" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "try {" << endl; + out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << '\n' + << indent() << "void* ctx = nullptr;" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "try {" << '\n'; indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << indent() << "args.read(iprot);" << endl << indent() - << "iprot->readMessageEnd();" << endl << indent() - << "uint32_t bytes = iprot->getTransport()->readEnd();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << indent() << "args.read(iprot);" << '\n' << indent() + << "iprot->readMessageEnd();" << '\n' << indent() + << "uint32_t bytes = iprot->getTransport()->readEnd();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n'; scope_down(out); // TODO(dreiss): Handle TExceptions? Expose to server? - out << indent() << "catch (const std::exception&) {" << endl << indent() - << " if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << " }" << endl << indent() << " return cob(false);" << endl << indent() - << "}" << endl; + out << indent() << "catch (const std::exception&) {" << '\n' << indent() + << " if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << " }" << '\n' << indent() << " return cob(false);" << '\n' << indent() + << "}" << '\n'; if (tfunction->is_oneway()) { - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n'; } // TODO(dreiss): Figure out a strategy for exceptions in async handlers. - out << indent() << "freer.unregister();" << endl; + out << indent() << "freer.unregister();" << '\n'; if (tfunction->is_oneway()) { // No return. Just hand off our cob. // TODO(dreiss): Call the cob immediately? out << indent() << "iface_->" << tfunction->get_name() << "(" - << "::std::bind(cob, true)" << endl; + << "::std::bind(cob, true)" << '\n'; indent_up(); indent_up(); } else { @@ -3707,38 +3794,38 @@ void t_cpp_generator::generate_process_function(t_service* tservice, out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix << "::*return_fn)(::std::function " << "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx" << ret_arg - << ") =" << endl; + << ") =" << '\n'; out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix - << "::return_" << tfunction->get_name() << ";" << endl; + << "::return_" << tfunction->get_name() << ";" << '\n'; if (!xceptions.empty()) { out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix << "::*throw_fn)(::std::function " << "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw) =" << endl; + << "::apache::thrift::TDelayedException* _throw) =" << '\n'; out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix - << "::throw_" << tfunction->get_name() << ";" << endl; + << "::throw_" << tfunction->get_name() << ";" << '\n'; } - out << indent() << "iface_->" << tfunction->get_name() << "(" << endl; + out << indent() << "iface_->" << tfunction->get_name() << "(" << '\n'; indent_up(); indent_up(); out << indent() << "::std::bind(return_fn, this, cob, seqid, oprot, ctx" << ret_placeholder << ")"; if (!xceptions.empty()) { - out << ',' << endl << indent() << "::std::bind(throw_fn, this, cob, seqid, oprot, " + out << ',' << '\n' << indent() << "::std::bind(throw_fn, this, cob, seqid, oprot, " << "ctx, ::std::placeholders::_1)"; } } // XXX Whitespace cleanup. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << ',' << endl << indent() << "args." << (*f_iter)->get_name(); + out << ',' << '\n' << indent() << "args." << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; indent_down(); indent_down(); scope_down(out); - out << endl; + out << '\n'; // Normal return. if (!tfunction->is_oneway()) { @@ -3748,128 +3835,128 @@ void t_cpp_generator::generate_process_function(t_service* tservice, ret_arg_name = ", _return"; } if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::return_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " - << prot_type << "* oprot, void* ctx" << ret_arg_decl << ')' << endl; + << prot_type << "* oprot, void* ctx" << ret_arg_decl << ')' << '\n'; scope_up(out); if (gen_templates_ && !specialized) { // If oprot is a Protocol_ instance, // use the specialized return function instead. - out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << endl - << indent() << "if (_oprot) {" << endl << indent() << " return return_" - << tfunction->get_name() << "(cob, seqid, _oprot, ctx" << ret_arg_name << ");" << endl - << indent() << "}" << endl << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" - << endl << endl; + out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' + << indent() << "if (_oprot) {" << '\n' << indent() << " return return_" + << tfunction->get_name() << "(cob, seqid, _oprot, ctx" << ret_arg_name << ");" << '\n' + << indent() << "}" << '\n' << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" + << '\n' << '\n'; } out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_presult result;" - << endl; + << '\n'; if (!tfunction->get_returntype()->is_void()) { // The const_cast here is unfortunate, but it would be a pain to avoid, // and we only do a write with this struct, which is const-safe. out << indent() << "result.success = const_cast<" << type_name(tfunction->get_returntype()) - << "*>(&_return);" << endl << indent() << "result.__isset.success = true;" << endl; + << "*>(&_return);" << '\n' << indent() << "result.__isset.success = true;" << '\n'; } // Serialize the result into a struct - out << endl << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() + out << '\n' << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" - << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl - << indent() << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" - << endl << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << endl - << indent() << "oprot->getTransport()->flush();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << indent() << "return cob(true);" << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" + << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' + << indent() << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" + << '\n' << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << '\n' + << indent() << "oprot->getTransport()->flush();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << indent() << "return cob(true);" << '\n'; scope_down(out); - out << endl; + out << '\n'; } // Exception return. if (!tfunction->is_oneway() && !xceptions.empty()) { if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::throw_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " << prot_type << "* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw)" << endl; + << "::apache::thrift::TDelayedException* _throw)" << '\n'; scope_up(out); if (gen_templates_ && !specialized) { // If oprot is a Protocol_ instance, // use the specialized throw function instead. - out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << endl - << indent() << "if (_oprot) {" << endl << indent() << " return throw_" - << tfunction->get_name() << "(cob, seqid, _oprot, ctx, _throw);" << endl << indent() - << "}" << endl << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl - << endl; + out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' + << indent() << "if (_oprot) {" << '\n' << indent() << " return throw_" + << tfunction->get_name() << "(cob, seqid, _oprot, ctx, _throw);" << '\n' << indent() + << "}" << '\n' << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << '\n' + << '\n'; } // Get the event handler context - out << endl << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() + out << '\n' << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n'; // Throw the TDelayedException, and catch the result out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;" - << endl << endl << indent() << "try {" << endl; + << '\n' << '\n' << indent() << "try {" << '\n'; indent_up(); - out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);" - << endl; // Is this possible? TBD. + out << indent() << "_throw->throw_it();" << '\n' << indent() << "return cob(false);" + << '\n'; // Is this possible? TBD. indent_down(); out << indent() << '}'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << " catch (" << type_name((*x_iter)->get_type()) << " &" << (*x_iter)->get_name() - << ") {" << endl; + << ") {" << '\n'; indent_up(); out << indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() - << ";" << endl << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" - << endl; + << ";" << '\n' << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" + << '\n'; scope_down(out); } // Handle the case where an undeclared exception is thrown - out << " catch (std::exception& e) {" << endl; + out << " catch (std::exception& e) {" << '\n'; indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() - << "::apache::thrift::TApplicationException x(e.what());" << endl << indent() + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() + << "::apache::thrift::TApplicationException x(e.what());" << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl << + << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n' << // We pass true to the cob here, since we did successfully write a // response, even though it is an exception response. // It looks like the argument is currently ignored, anyway. - indent() << "return cob(true);" << endl; + indent() << "return cob(true);" << '\n'; scope_down(out); // Serialize the result into a struct - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" - << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl - << indent() << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" - << endl << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << endl - << indent() << "oprot->getTransport()->flush();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << indent() << "return cob(true);" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" + << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' + << indent() << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" + << '\n' << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << '\n' + << indent() << "oprot->getTransport()->flush();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << indent() << "return cob(true);" << '\n'; scope_down(out); - out << endl; + out << '\n'; } // for each function } // cob style } @@ -3889,58 +3976,58 @@ void t_cpp_generator::generate_service_skeleton(t_service* tservice) { ofstream_with_content_based_conditional_update f_skeleton; f_skeleton.open(f_skeleton_name.c_str()); - f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << endl - << "// You should copy it to another filename to avoid overwriting it." << endl << endl - << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl << endl - << "using namespace ::apache::thrift;" << endl - << "using namespace ::apache::thrift::protocol;" << endl - << "using namespace ::apache::thrift::transport;" << endl - << "using namespace ::apache::thrift::server;" << endl << endl; + f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << '\n' + << "// You should copy it to another filename to avoid overwriting it." << '\n' << '\n' + << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' << '\n' + << "using namespace ::apache::thrift;" << '\n' + << "using namespace ::apache::thrift::protocol;" << '\n' + << "using namespace ::apache::thrift::transport;" << '\n' + << "using namespace ::apache::thrift::server;" << '\n' << '\n'; // the following code would not compile: // using namespace ; // using namespace ::; if ((!ns.empty()) && (ns.compare(" ::") != 0)) { - f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << endl << endl; + f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << '\n' << '\n'; } - f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << endl - << " public:" << endl; + f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << '\n' + << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "Handler() {" << endl << indent() - << " // Your initialization goes here" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << svcname << "Handler() {" << '\n' << indent() + << " // Your initialization goes here" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_skeleton, *f_iter); - f_skeleton << indent() << function_signature(*f_iter, "") << " {" << endl << indent() - << " // Your implementation goes here" << endl << indent() << " printf(\"" - << (*f_iter)->get_name() << "\\n\");" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << function_signature(*f_iter, "") << " {" << '\n' << indent() + << " // Your implementation goes here" << '\n' << indent() << " printf(\"" + << (*f_iter)->get_name() << "\\n\");" << '\n' << indent() << "}" << '\n' << '\n'; } indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; - f_skeleton << indent() << "int main(int argc, char **argv) {" << endl; + f_skeleton << indent() << "int main(int argc, char **argv) {" << '\n'; indent_up(); f_skeleton - << indent() << "int port = 9090;" << endl << indent() << "::std::shared_ptr<" << svcname - << "Handler> handler(new " << svcname << "Handler());" << endl << indent() - << "::std::shared_ptr processor(new " << svcname << "Processor(handler));" << endl + << indent() << "int port = 9090;" << '\n' << indent() << "::std::shared_ptr<" << svcname + << "Handler> handler(new " << svcname << "Handler());" << '\n' << indent() + << "::std::shared_ptr processor(new " << svcname << "Processor(handler));" << '\n' << indent() << "::std::shared_ptr serverTransport(new TServerSocket(port));" - << endl << indent() - << "::std::shared_ptr transportFactory(new TBufferedTransportFactory());" << endl + << '\n' << indent() + << "::std::shared_ptr transportFactory(new TBufferedTransportFactory());" << '\n' << indent() << "::std::shared_ptr protocolFactory(new TBinaryProtocolFactory());" - << endl << endl << indent() + << '\n' << '\n' << indent() << "TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);" - << endl << indent() << "server.serve();" << endl << indent() << "return 0;" << endl; + << '\n' << indent() << "server.serve();" << '\n' << indent() << "return 0;" << '\n'; indent_down(); - f_skeleton << "}" << endl << endl; + f_skeleton << "}" << '\n' << '\n'; // Close the files f_skeleton.close(); @@ -3972,6 +4059,9 @@ void t_cpp_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_VOID: throw "compiler error: cannot serialize void field in a struct: " + name; break; + case t_base_type::TYPE_UUID: + out << "readUUID(" << name << ");"; + break; case t_base_type::TYPE_STRING: if (type->is_binary()) { out << "readBinary(" << name << ");"; @@ -3998,14 +4088,14 @@ void t_cpp_generator::generate_deserialize_field(ostream& out, out << "readDouble(" << name << ");"; break; default: - throw "compiler error: no C++ reader for base type " + t_base_type::t_base_name(tbase) + name; + throw "compiler error: no C++ reader for base type " + t_base_type::t_base_name(tbase) + " " + name; } - out << endl; + out << '\n'; } else if (type->is_enum()) { string t = tmp("ecast"); - out << indent() << "int32_t " << t << ";" << endl << indent() << "xfer += iprot->readI32(" << t - << ");" << endl << indent() << name << " = static_cast<" - << type_name(type) << ">(" << t << ");" << endl; + out << indent() << "int32_t " << t << ";" << '\n' << indent() << "xfer += iprot->readI32(" << t + << ");" << '\n' << indent() << name << " = static_cast<" + << type_name(type) << ">(" << t << ");" << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -4024,22 +4114,22 @@ void t_cpp_generator::generate_deserialize_struct(ostream& out, string prefix, bool pointer) { if (pointer) { - indent(out) << "if (!" << prefix << ") { " << endl; + indent(out) << "if (!" << prefix << ") { " << '\n'; indent(out) << " " << prefix << " = ::std::shared_ptr<" << type_name(tstruct) << ">(new " - << type_name(tstruct) << ");" << endl; - indent(out) << "}" << endl; - indent(out) << "xfer += " << prefix << "->read(iprot);" << endl; - indent(out) << "bool wasSet = false;" << endl; + << type_name(tstruct) << ");" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "xfer += " << prefix << "->read(iprot);" << '\n'; + indent(out) << "bool wasSet = false;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator f_iter; for (f_iter = members.begin(); f_iter != members.end(); ++f_iter) { indent(out) << "if (" << prefix << "->__isset." << (*f_iter)->get_name() - << ") { wasSet = true; }" << endl; + << ") { wasSet = true; }" << '\n'; } - indent(out) << "if (!wasSet) { " << prefix << ".reset(); }" << endl; + indent(out) << "if (!wasSet) { " << prefix << ".reset(); }" << '\n'; } else { - indent(out) << "xfer += " << prefix << ".read(iprot);" << endl; + indent(out) << "xfer += " << prefix << ".read(iprot);" << '\n'; } } @@ -4054,28 +4144,28 @@ void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype t_container* tcontainer = (t_container*)ttype; bool use_push = tcontainer->has_cpp_name(); - indent(out) << prefix << ".clear();" << endl << indent() << "uint32_t " << size << ";" << endl; + indent(out) << prefix << ".clear();" << '\n' << indent() << "uint32_t " << size << ";" << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "::apache::thrift::protocol::TType " << ktype << ";" << endl << indent() - << "::apache::thrift::protocol::TType " << vtype << ";" << endl << indent() - << "xfer += iprot->readMapBegin(" << ktype << ", " << vtype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << ktype << ";" << '\n' << indent() + << "::apache::thrift::protocol::TType " << vtype << ";" << '\n' << indent() + << "xfer += iprot->readMapBegin(" << ktype << ", " << vtype << ", " << size << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << endl << indent() - << "xfer += iprot->readSetBegin(" << etype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << '\n' << indent() + << "xfer += iprot->readSetBegin(" << etype << ", " << size << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << endl << indent() - << "xfer += iprot->readListBegin(" << etype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << '\n' << indent() + << "xfer += iprot->readListBegin(" << etype << ", " << size << ");" << '\n'; if (!use_push) { - indent(out) << prefix << ".resize(" << size << ");" << endl; + indent(out) << prefix << ".resize(" << size << ");" << '\n'; } } // For loop iterates over elements string i = tmp("_i"); - out << indent() << "uint32_t " << i << ";" << endl << indent() << "for (" << i << " = 0; " << i - << " < " << size << "; ++" << i << ")" << endl; + out << indent() << "uint32_t " << i << ";" << '\n' << indent() << "for (" << i << " = 0; " << i + << " < " << size << "; ++" << i << ")" << '\n'; scope_up(out); @@ -4091,11 +4181,11 @@ void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype // Read container end if (ttype->is_map()) { - indent(out) << "xfer += iprot->readMapEnd();" << endl; + indent(out) << "xfer += iprot->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "xfer += iprot->readSetEnd();" << endl; + indent(out) << "xfer += iprot->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "xfer += iprot->readListEnd();" << endl; + indent(out) << "xfer += iprot->readListEnd();" << '\n'; } scope_down(out); @@ -4110,11 +4200,11 @@ void t_cpp_generator::generate_deserialize_map_element(ostream& out, t_map* tmap t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - out << indent() << declare_field(&fkey) << endl; + out << indent() << declare_field(&fkey) << '\n'; generate_deserialize_field(out, &fkey); indent(out) << declare_field(&fval, false, false, false, true) << " = " << prefix << "[" << key - << "];" << endl; + << "];" << '\n'; generate_deserialize_field(out, &fval); } @@ -4123,11 +4213,11 @@ void t_cpp_generator::generate_deserialize_set_element(ostream& out, t_set* tset string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".insert(" << elem << ");" << endl; + indent(out) << prefix << ".insert(" << elem << ");" << '\n'; } void t_cpp_generator::generate_deserialize_list_element(ostream& out, @@ -4138,9 +4228,9 @@ void t_cpp_generator::generate_deserialize_list_element(ostream& out, if (use_push) { string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push_back(" << elem << ");" << endl; + indent(out) << prefix << ".push_back(" << elem << ");" << '\n'; } else { t_field felem(tlist->get_elem_type(), prefix + "[" + index + "]"); generate_deserialize_field(out, &felem); @@ -4180,6 +4270,9 @@ void t_cpp_generator::generate_serialize_field(ostream& out, case t_base_type::TYPE_VOID: throw "compiler error: cannot serialize void field in a struct: " + name; break; + case t_base_type::TYPE_UUID: + out << "writeUUID(" << name << ");"; + break; case t_base_type::TYPE_STRING: if (type->is_binary()) { out << "writeBinary(" << name << ");"; @@ -4207,12 +4300,12 @@ void t_cpp_generator::generate_serialize_field(ostream& out, break; default: throw "compiler error: no C++ writer for base type " + t_base_type::t_base_name(tbase) - + name; + + " " + name; } } else if (type->is_enum()) { out << "writeI32(static_cast(" << name << "));"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n", name.c_str(), @@ -4231,15 +4324,15 @@ void t_cpp_generator::generate_serialize_struct(ostream& out, string prefix, bool pointer) { if (pointer) { - indent(out) << "if (" << prefix << ") {" << endl; - indent(out) << " xfer += " << prefix << "->write(oprot); " << endl; + indent(out) << "if (" << prefix << ") {" << '\n'; + indent(out) << " xfer += " << prefix << "->write(oprot); " << '\n'; indent(out) << "} else {" - << "oprot->writeStructBegin(\"" << tstruct->get_name() << "\"); " << endl; - indent(out) << " oprot->writeStructEnd();" << endl; - indent(out) << " oprot->writeFieldStop();" << endl; - indent(out) << "}" << endl; + << "oprot->writeStructBegin(\"" << tstruct->get_name() << "\"); " << '\n'; + indent(out) << " oprot->writeStructEnd();" << '\n'; + indent(out) << " oprot->writeFieldStop();" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "xfer += " << prefix << ".write(oprot);" << endl; + indent(out) << "xfer += " << prefix << ".write(oprot);" << '\n'; } } @@ -4249,21 +4342,21 @@ void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { indent(out) << "xfer += oprot->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } else if (ttype->is_set()) { indent(out) << "xfer += oprot->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "xfer += oprot->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } string iter = tmp("_iter"); - out << indent() << type_name(ttype) << "::const_iterator " << iter << ";" << endl << indent() + out << indent() << type_name(ttype) << "::const_iterator " << iter << ";" << '\n' << indent() << "for (" << iter << " = " << prefix << ".begin(); " << iter << " != " << prefix - << ".end(); ++" << iter << ")" << endl; + << ".end(); ++" << iter << ")" << '\n'; scope_up(out); if (ttype->is_map()) { generate_serialize_map_element(out, (t_map*)ttype, iter); @@ -4275,11 +4368,11 @@ void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "xfer += oprot->writeMapEnd();" << endl; + indent(out) << "xfer += oprot->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "xfer += oprot->writeSetEnd();" << endl; + indent(out) << "xfer += oprot->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "xfer += oprot->writeListEnd();" << endl; + indent(out) << "xfer += oprot->writeListEnd();" << '\n'; } scope_down(out); @@ -4408,7 +4501,7 @@ string t_cpp_generator::type_name(t_type* ttype, bool in_typedef, bool arg) { return bname; } - if (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) { + if ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) || ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_UUID))) { return "const " + bname + "&"; } else { return "const " + bname; @@ -4494,6 +4587,8 @@ string t_cpp_generator::base_type_name(t_base_type::t_base tbase) { return "int64_t"; case t_base_type::TYPE_DOUBLE: return "double"; + case t_base_type::TYPE_UUID: + return "apache::thrift::TUuid"; default: throw "compiler error: no C++ base type name for base type " + t_base_type::t_base_name(tbase); } @@ -4528,30 +4623,35 @@ string t_cpp_generator::declare_field(t_field* tfield, result += " " + tfield->get_name(); if (init) { t_type* type = get_true_type(tfield->get_type()); + if (t_const_value* cv = tfield->get_value()) { + result += " = " + render_const_value(nullptr, tfield->get_name(), type, cv); + } else { + if (type->is_base_type()) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - if (type->is_base_type()) { - t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - switch (tbase) { - case t_base_type::TYPE_VOID: - case t_base_type::TYPE_STRING: - break; - case t_base_type::TYPE_BOOL: - result += " = false"; - break; - case t_base_type::TYPE_I8: - case t_base_type::TYPE_I16: - case t_base_type::TYPE_I32: - case t_base_type::TYPE_I64: - result += " = 0"; - break; - case t_base_type::TYPE_DOUBLE: - result += " = 0.0"; - break; - default: - throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase); + switch (tbase) { + case t_base_type::TYPE_VOID: + case t_base_type::TYPE_STRING: + case t_base_type::TYPE_UUID: + break; + case t_base_type::TYPE_BOOL: + result += " = false"; + break; + case t_base_type::TYPE_I8: + case t_base_type::TYPE_I16: + case t_base_type::TYPE_I32: + case t_base_type::TYPE_I64: + result += " = 0"; + break; + case t_base_type::TYPE_DOUBLE: + result += " = 0.0"; + break; + default: + throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase); + } + } else if (type->is_enum()) { + result += " = static_cast<" + type_name(type) + ">(0)"; } - } else if (type->is_enum()) { - result += " = static_cast<" + type_name(type) + ">(0)"; } } if (!reference) { @@ -4661,6 +4761,8 @@ string t_cpp_generator::type_to_enum(t_type* type) { return "::apache::thrift::protocol::T_I64"; case t_base_type::TYPE_DOUBLE: return "::apache::thrift::protocol::T_DOUBLE"; + case t_base_type::TYPE_UUID: + return "::apache::thrift::protocol::T_UUID"; default: break; } @@ -4699,6 +4801,7 @@ bool t_cpp_generator::is_struct_storage_not_throwing(t_struct* tstruct) const { case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: case t_base_type::TYPE_DOUBLE: + case t_base_type::TYPE_UUID: continue; case t_base_type::TYPE_VOID: case t_base_type::TYPE_STRING: diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc index 38194c20719..61988dfc491 100644 --- a/compiler/cpp/src/thrift/generate/t_d_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc @@ -43,8 +43,6 @@ using std::set; using std::string; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * D code generator. * @@ -105,7 +103,7 @@ class t_d_generator : public t_oop_generator { // Print header f_types_ << autogen_comment() << "module " << render_package(*program_) << program_name_ - << "_types;" << endl << endl; + << "_types;" << '\n' << '\n'; print_default_imports(f_types_); @@ -113,10 +111,10 @@ class t_d_generator : public t_oop_generator { const vector& includes = program_->get_includes(); for (auto include : includes) { f_types_ << "public import " << render_package(*include) << include->get_name() - << "_types;" << endl; + << "_types;" << '\n'; } if (!includes.empty()) - f_types_ << endl; + f_types_ << '\n'; } void close_generator() override { @@ -131,22 +129,22 @@ class t_d_generator : public t_oop_generator { f_consts.open(f_consts_name.c_str()); f_consts << autogen_comment() << "module " << render_package(*program_) << program_name_ - << "_constants;" << endl << endl; + << "_constants;" << '\n' << '\n'; print_default_imports(f_consts); - f_consts << "import " << render_package(*get_program()) << program_name_ << "_types;" << endl - << endl; + f_consts << "import " << render_package(*get_program()) << program_name_ << "_types;" << '\n' + << '\n'; vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { this->emit_doc(*c_iter, f_consts); string name = suffix_if_reserved((*c_iter)->get_name()); t_type* type = (*c_iter)->get_type(); - indent(f_consts) << "immutable(" << render_type_name(type) << ") " << name << ";" << endl; + indent(f_consts) << "immutable(" << render_type_name(type) << ") " << name << ";" << '\n'; } - f_consts << endl << "shared static this() {" << endl; + f_consts << '\n' << "shared static this() {" << '\n'; indent_up(); bool first = true; @@ -154,24 +152,24 @@ class t_d_generator : public t_oop_generator { if (first) { first = false; } else { - f_consts << endl; + f_consts << '\n'; } t_type* type = (*c_iter)->get_type(); indent(f_consts) << suffix_if_reserved((*c_iter)->get_name()) << " = "; if (!is_immutable_type(type)) { f_consts << "cast(immutable(" << render_type_name(type) << ")) "; } - f_consts << render_const_value(type, (*c_iter)->get_value()) << ";" << endl; + f_consts << render_const_value(type, (*c_iter)->get_value()) << ";" << '\n'; } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; } } void generate_typedef(t_typedef* ttypedef) override { this->emit_doc(ttypedef, f_types_); f_types_ << indent() << "alias " << render_type_name(ttypedef->get_type()) << " " - << ttypedef->get_symbolic() << ";" << endl << endl; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } void generate_enum(t_enum* tenum) override { @@ -179,7 +177,7 @@ class t_d_generator : public t_oop_generator { this->emit_doc(tenum, f_types_); string enum_name = suffix_if_reserved(tenum->get_name()); - f_types_ << indent() << "enum " << enum_name << " {" << endl; + f_types_ << indent() << "enum " << enum_name << " {" << '\n'; indent_up(); @@ -190,11 +188,11 @@ class t_d_generator : public t_oop_generator { f_types_ << " = " << (*c_iter)->get_value() << ","; } - f_types_ << endl; + f_types_ << '\n'; indent_down(); - indent(f_types_) << "}" << endl; + indent(f_types_) << "}" << '\n'; - f_types_ << endl; + f_types_ << '\n'; } void generate_struct(t_struct* tstruct) override { @@ -213,19 +211,19 @@ class t_d_generator : public t_oop_generator { ofstream_with_content_based_conditional_update f_service; f_service.open(f_servicename.c_str()); f_service << autogen_comment() << "module " << suffix_if_reserved(render_package(*program_)) << svc_name << ";" - << endl << endl; + << '\n' << '\n'; print_default_imports(f_service); - f_service << "import " << suffix_if_reserved(render_package(*get_program())) << program_name_ << "_types;" << endl; + f_service << "import " << suffix_if_reserved(render_package(*get_program())) << program_name_ << "_types;" << '\n'; t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_service << "import " << suffix_if_reserved(render_package(*(extends_service->get_program()))) - << suffix_if_reserved(extends_service->get_name()) << ";" << endl; + << suffix_if_reserved(extends_service->get_name()) << ";" << '\n'; } - f_service << endl; + f_service << '\n'; string extends = ""; if (tservice->get_extends() != nullptr) { @@ -233,7 +231,7 @@ class t_d_generator : public t_oop_generator { } this->emit_doc(tservice, f_service); - f_service << indent() << "interface " << svc_name << extends << " {" << endl; + f_service << indent() << "interface " << svc_name << extends << " {" << '\n'; indent_up(); // Collect all the exception types service methods can throw so we can @@ -247,7 +245,7 @@ class t_d_generator : public t_oop_generator { this->emit_doc(*fn_iter, f_service); f_service << indent(); print_function_signature(f_service, *fn_iter); - f_service << ";" << endl; + f_service << ";" << '\n'; const vector& exceptions = (*fn_iter)->get_xceptions()->get_members(); vector::const_iterator ex_iter; @@ -258,13 +256,13 @@ class t_d_generator : public t_oop_generator { // Alias the exception types into the current scope. if (!exception_types.empty()) - f_service << endl; + f_service << '\n'; set::const_iterator et_iter; for (et_iter = exception_types.begin(); et_iter != exception_types.end(); ++et_iter) { indent(f_service) << "alias " << render_package(*(*et_iter)->get_program()) << (*et_iter)->get_program()->get_name() << "_types" << "." << (*et_iter)->get_name() << " " << (*et_iter)->get_name() << ";" - << endl; + << '\n'; } // Write the method metadata. @@ -283,7 +281,7 @@ class t_d_generator : public t_oop_generator { meta << ","; } - meta << endl << indent() << "TMethodMeta(`" << suffix_if_reserved((*fn_iter)->get_name()) << "`, " << endl; + meta << '\n' << indent() << "TMethodMeta(`" << suffix_if_reserved((*fn_iter)->get_name()) << "`, " << '\n'; indent_up(); indent(meta) << "["; @@ -309,7 +307,7 @@ class t_d_generator : public t_oop_generator { meta << "]"; if (!(*fn_iter)->get_xceptions()->get_members().empty() || (*fn_iter)->is_oneway()) { - meta << "," << endl << indent() << "["; + meta << "," << '\n' << indent() << "["; bool first = true; const vector& exceptions = (*fn_iter)->get_xceptions()->get_members(); @@ -329,22 +327,22 @@ class t_d_generator : public t_oop_generator { } if ((*fn_iter)->is_oneway()) { - meta << "," << endl << indent() << "TMethodType.ONEWAY"; + meta << "," << '\n' << indent() << "TMethodType.ONEWAY"; } indent_down(); - meta << endl << indent() << ")"; + meta << '\n' << indent() << ")"; } indent_down(); string meta_str(meta.str()); if (!meta_str.empty()) { - f_service << endl << indent() << "enum methodMeta = [" << meta_str << endl << indent() << "];" - << endl; + f_service << '\n' << indent() << "enum methodMeta = [" << meta_str << '\n' << indent() << "];" + << '\n'; } indent_down(); - indent(f_service) << "}" << endl; + indent(f_service) << "}" << '\n'; // Server skeleton generation. string f_skeletonname = package_dir_ + svc_name + "_server.skeleton.d"; @@ -358,14 +356,14 @@ class t_d_generator : public t_oop_generator { if (!doc->has_doc()) { return; } - indent(out) << "/**" << std::endl; + indent(out) << "/**" << '\n'; indent_up(); - // No endl -- comments reliably have a newline at the end. + // No line break -- comments reliably have a newline at the end. // This is true even for stuff like: // /** method infos */ void foo(/** huh?*/ 1: i64 stuff) indent(out) << doc->get_doc(); indent_down(); - indent(out) << "*/" << std::endl; + indent(out) << "*/" << '\n'; } private: @@ -376,59 +374,59 @@ class t_d_generator : public t_oop_generator { void print_server_skeleton(ostream& out, t_service* tservice) { string svc_name = suffix_if_reserved(tservice->get_name()); - out << "/*" << endl - << " * This auto-generated skeleton file illustrates how to build a server. If you" << endl - << " * intend to customize it, you should edit a copy with another file name to " << endl - << " * avoid overwriting it when running the generator again." << endl << " */" << endl - << "module " << render_package(*tservice->get_program()) << svc_name << "_server;" << endl - << endl << "import std.stdio;" << endl << "import thrift.codegen.processor;" << endl - << "import thrift.protocol.binary;" << endl << "import thrift.server.simple;" << endl - << "import thrift.server.transport.socket;" << endl << "import thrift.transport.buffered;" - << endl << "import thrift.util.hashset;" << endl << endl << "import " - << render_package(*tservice->get_program()) << svc_name << ";" << endl << "import " - << render_package(*get_program()) << program_name_ << "_types;" << endl << endl << endl - << "class " << svc_name << "Handler : " << svc_name << " {" << endl; + out << "/*" << '\n' + << " * This auto-generated skeleton file illustrates how to build a server. If you" << '\n' + << " * intend to customize it, you should edit a copy with another file name to " << '\n' + << " * avoid overwriting it when running the generator again." << '\n' << " */" << '\n' + << "module " << render_package(*tservice->get_program()) << svc_name << "_server;" << '\n' + << '\n' << "import std.stdio;" << '\n' << "import thrift.codegen.processor;" << '\n' + << "import thrift.protocol.binary;" << '\n' << "import thrift.server.simple;" << '\n' + << "import thrift.server.transport.socket;" << '\n' << "import thrift.transport.buffered;" + << '\n' << "import thrift.util.hashset;" << '\n' << '\n' << "import " + << render_package(*tservice->get_program()) << svc_name << ";" << '\n' << "import " + << render_package(*get_program()) << program_name_ << "_types;" << '\n' << '\n' << '\n' + << "class " << svc_name << "Handler : " << svc_name << " {" << '\n'; indent_up(); - out << indent() << "this() {" << endl << indent() << " // Your initialization goes here." - << endl << indent() << "}" << endl << endl; + out << indent() << "this() {" << '\n' << indent() << " // Your initialization goes here." + << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { out << indent(); print_function_signature(out, *f_iter); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "// Your implementation goes here." << endl << indent() << "writeln(\"" - << suffix_if_reserved((*f_iter)->get_name()) << " called\");" << endl; + out << indent() << "// Your implementation goes here." << '\n' << indent() << "writeln(\"" + << suffix_if_reserved((*f_iter)->get_name()) << " called\");" << '\n'; t_type* rt = (*f_iter)->get_returntype(); if (!rt->is_void()) { - indent(out) << "return typeof(return).init;" << endl; + indent(out) << "return typeof(return).init;" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; - out << indent() << "void main() {" << endl; + out << indent() << "void main() {" << '\n'; indent_up(); - out << indent() << "auto protocolFactory = new TBinaryProtocolFactory!();" << endl << indent() + out << indent() << "auto protocolFactory = new TBinaryProtocolFactory!();" << '\n' << indent() << "auto processor = new TServiceProcessor!" << svc_name << "(new " << svc_name - << "Handler);" << endl << indent() << "auto serverTransport = new TServerSocket(9090);" - << endl << indent() << "auto transportFactory = new TBufferedTransportFactory;" << endl - << indent() << "auto server = new TSimpleServer(" << endl << indent() - << " processor, serverTransport, transportFactory, protocolFactory);" << endl << indent() - << "server.serve();" << endl; + << "Handler);" << '\n' << indent() << "auto serverTransport = new TServerSocket(9090);" + << '\n' << indent() << "auto transportFactory = new TBufferedTransportFactory;" << '\n' + << indent() << "auto server = new TSimpleServer(" << '\n' << indent() + << " processor, serverTransport, transportFactory, protocolFactory);" << '\n' << indent() + << "server.serve();" << '\n'; indent_down(); - out << "}" << endl; + out << "}" << '\n'; } /** @@ -439,9 +437,9 @@ class t_d_generator : public t_oop_generator { const vector& members = tstruct->get_members(); if (is_exception) { - indent(out) << "class " << suffix_if_reserved(tstruct->get_name()) << " : TException {" << endl; + indent(out) << "class " << suffix_if_reserved(tstruct->get_name()) << " : TException {" << '\n'; } else { - indent(out) << "struct " << suffix_if_reserved(tstruct->get_name()) << " {" << endl; + indent(out) << "struct " << suffix_if_reserved(tstruct->get_name()) << " {" << '\n'; } indent_up(); @@ -449,11 +447,11 @@ class t_d_generator : public t_oop_generator { vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << render_type_name((*m_iter)->get_type()) << " " << suffix_if_reserved((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } if (!members.empty()) - indent(out) << endl; + indent(out) << '\n'; indent(out) << "mixin TStructHelpers!("; if (!members.empty()) { @@ -471,7 +469,7 @@ class t_d_generator : public t_oop_generator { } else { out << ","; } - out << endl; + out << '\n'; indent(out) << "TFieldMeta(`" << suffix_if_reserved((*m_iter)->get_name()) << "`, " << (*m_iter)->get_key(); @@ -485,13 +483,13 @@ class t_d_generator : public t_oop_generator { } indent_down(); - out << endl << indent() << "]"; + out << '\n' << indent() << "]"; } - out << ");" << endl; + out << ");" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -559,13 +557,13 @@ class t_d_generator : public t_oop_generator { } else if (type->is_enum()) { out << "cast(" << render_type_name(type) << ")" << value->get_integer(); } else { - out << "{" << endl; + out << "{" << '\n'; indent_up(); - indent(out) << render_type_name(type) << " v;" << endl; + indent(out) << render_type_name(type) << " v;" << '\n'; if (type->is_struct() || type->is_xception()) { indent(out) << "v = " << (type->is_xception() ? "new " : "") << render_type_name(type) - << "();" << endl; + << "();" << '\n'; const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -583,7 +581,7 @@ class t_d_generator : public t_oop_generator { + v_iter->first->get_string(); } string val = render_const_value(field_type, v_iter->second); - indent(out) << "v.set!`" << v_iter->first->get_string() << "`(" << val << ");" << endl; + indent(out) << "v.set!`" << v_iter->first->get_string() << "`(" << val << ");" << '\n'; } } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); @@ -597,7 +595,7 @@ class t_d_generator : public t_oop_generator { if (!is_immutable_type(ktype)) { out << "cast(immutable(" << render_type_name(ktype) << "))"; } - out << key << "] = " << val << ";" << endl; + out << key << "] = " << val << ";" << '\n'; } } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); @@ -605,7 +603,7 @@ class t_d_generator : public t_oop_generator { vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "v ~= " << val << ";" << endl; + indent(out) << "v ~= " << val << ";" << '\n'; } } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); @@ -613,12 +611,12 @@ class t_d_generator : public t_oop_generator { vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "v ~= " << val << ";" << endl; + indent(out) << "v ~= " << val << ";" << '\n'; } } else { throw "Compiler error: Invalid type in render_const_value: " + type->get_name(); } - indent(out) << "return v;" << endl; + indent(out) << "return v;" << '\n'; indent_down(); indent(out) << "}()"; @@ -728,8 +726,8 @@ class t_d_generator : public t_oop_generator { */ void print_default_imports(ostream& out) { - indent(out) << "import thrift.base;" << endl << "import thrift.codegen.base;" << endl - << "import thrift.util.hashset;" << endl << endl; + indent(out) << "import thrift.base;" << '\n' << "import thrift.codegen.base;" << '\n' + << "import thrift.util.hashset;" << '\n' << '\n'; } /** diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc index fda989b24c6..34f9d82e242 100644 --- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc @@ -37,9 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes -static const string endl2 = "\n\n"; - /** * Use the current Thrift version for static libraries. When releasing, update * the version in these files. @@ -89,11 +86,11 @@ class t_dart_generator : public t_oop_generator { } void scope_up(std::ostream& out, std::string prefix=" ") { - out << prefix << "{" << endl; + out << prefix << "{" << '\n'; indent_up(); } - void scope_down(std::ostream& out, std::string postfix=endl) { + void scope_down(std::ostream& out, std::string postfix="\n") { indent_down(); indent(out) << "}" << postfix; } @@ -147,7 +144,8 @@ class t_dart_generator : public t_oop_generator { t_type* type, t_const_value* value, bool in_static, - bool defval = false); + bool defval = false, + bool inlineOnly = false); std::string render_const_value(ostream& out, std::string name, t_type* type, @@ -240,6 +238,7 @@ class t_dart_generator : public t_oop_generator { std::string dart_thrift_imports(); std::string type_name(t_type* ttype); std::string base_type_name(t_base_type* tbase); + std::string type_name_instantiate(t_type* ttype); std::string declare_field(t_field* tfield, bool init = false); std::string function_signature(t_function* tfunction); std::string argument_list(t_struct* tstruct); @@ -253,6 +252,10 @@ class t_dart_generator : public t_oop_generator { || ttype->is_string(); } + std::string get_type_suffix(t_type* ttype) { + return type_can_be_null(ttype) ? "?" : ""; + } + vector split(const string& s, char delim) { vector elems; stringstream ss(s); @@ -339,7 +342,7 @@ string t_dart_generator::dart_library(string file_name) { * @return List of imports for services */ string t_dart_generator::service_imports() { - return "import 'dart:async';" + endl; + return string("import 'dart:async';") + "\n"; } /** @@ -348,14 +351,14 @@ string t_dart_generator::service_imports() { * @return List of imports necessary for thrift */ string t_dart_generator::dart_thrift_imports() { - string imports = "import 'dart:typed_data' show Uint8List;" + endl + - "import 'package:thrift/thrift.dart';" + endl; + string imports = string("import 'dart:typed_data' show Uint8List;") + "\n" + + string("import 'package:thrift/thrift.dart';") + "\n"; // add import for this library if (package_prefix_.empty()) { - imports += "import 'package:" + library_name_ + "/" + library_name_ + ".dart';" + endl; + imports += "import 'package:" + library_name_ + "/" + library_name_ + ".dart';" + "\n"; } else { - imports += "import 'package:" + package_prefix_ + library_name_ + ".dart';" + endl; + imports += "import 'package:" + package_prefix_ + library_name_ + ".dart';" + "\n"; } // add imports for included thrift files @@ -364,9 +367,9 @@ string t_dart_generator::dart_thrift_imports() { string include_name = find_library_name(include); string named_import = "t_" + include_name; if (package_prefix_.empty()) { - imports += "import 'package:" + include_name + "/" + include_name + ".dart' as " + named_import + ";" + endl; + imports += "import 'package:" + include_name + "/" + include_name + ".dart' as " + named_import + ";" + "\n"; } else { - imports += "import 'package:" + package_prefix_ + include_name + ".dart' as " + named_import + ";" + endl; + imports += "import 'package:" + package_prefix_ + include_name + ".dart' as " + named_import + ";" + "\n"; } } @@ -395,8 +398,8 @@ void t_dart_generator::generate_dart_library() { ofstream_with_content_based_conditional_update f_library; f_library.open(f_library_name.c_str()); - f_library << autogen_comment() << endl; - f_library << "library " << library_prefix_ << library_name_ << ";" << endl2; + f_library << autogen_comment() << '\n'; + f_library << "library " << library_prefix_ << library_name_ << ";" << '\n' << '\n'; f_library << library_exports_; f_library.close(); @@ -409,7 +412,7 @@ void t_dart_generator::export_class_to_library(string file_name, string class_na } else { subdir = library_name_; } - library_exports_ += "export '" + subdir + "/" + file_name + ".dart' show " + class_name + ";" + endl; + library_exports_ += "export '" + subdir + "/" + file_name + ".dart' show " + class_name + ";" + "\n"; } void t_dart_generator::generate_dart_pubspec() { @@ -417,30 +420,30 @@ void t_dart_generator::generate_dart_pubspec() { ofstream_with_content_based_conditional_update f_pubspec; f_pubspec.open(f_pubspec_name.c_str()); - indent(f_pubspec) << "name: " << library_name_ << endl; - indent(f_pubspec) << "version: 0.0.1" << endl; - indent(f_pubspec) << "description: Autogenerated by Thrift Compiler" << endl; - f_pubspec << endl; + indent(f_pubspec) << "name: " << library_name_ << '\n'; + indent(f_pubspec) << "version: 0.0.1" << '\n'; + indent(f_pubspec) << "description: Autogenerated by Thrift Compiler" << '\n'; + f_pubspec << '\n'; - indent(f_pubspec) << "environment:" << endl; + indent(f_pubspec) << "environment:" << '\n'; indent_up(); - indent(f_pubspec) << "sdk: '>=1.24.3 <3.0.0'" << endl; + indent(f_pubspec) << "sdk: '>=2.12.0 <4.0.0'" << '\n'; indent_down(); - f_pubspec << endl; + f_pubspec << '\n'; - indent(f_pubspec) << "dependencies:" << endl; + indent(f_pubspec) << "dependencies:" << '\n'; indent_up(); if (pubspec_lib_.empty()) { // default to relative path within working directory, which works for tests - indent(f_pubspec) << "thrift: # ^" << dart_thrift_version << endl; + indent(f_pubspec) << "thrift: # ^" << dart_thrift_version << '\n'; indent_up(); - indent(f_pubspec) << "path: ../../../../lib/dart" << endl; + indent(f_pubspec) << "path: ../../../../lib/dart" << '\n'; indent_down(); } else { const vector lines = split(pubspec_lib_, '|'); for (const auto & line : lines) { - indent(f_pubspec) << line << endl; + indent(f_pubspec) << line << '\n'; } } @@ -448,14 +451,14 @@ void t_dart_generator::generate_dart_pubspec() { const vector& includes = program_->get_includes(); for (auto include : includes) { string include_name = find_library_name(include); - indent(f_pubspec) << include_name << ":" << endl; + indent(f_pubspec) << include_name << ":" << '\n'; indent_up(); - indent(f_pubspec) << "path: ../" << include_name << endl; + indent(f_pubspec) << "path: ../" << include_name << '\n'; indent_down(); } indent_down(); - f_pubspec << endl; + f_pubspec << '\n'; f_pubspec.close(); } @@ -483,7 +486,7 @@ void t_dart_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and add library - f_enum << autogen_comment() << dart_library(file_name) << endl; + f_enum << autogen_comment() << dart_library(file_name) << '\n'; string class_name = tenum->get_name(); export_class_to_library(file_name, class_name); @@ -495,34 +498,34 @@ void t_dart_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); indent(f_enum) << "static const int " << (*c_iter)->get_name() << " = " << value << ";" - << endl; + << '\n'; } // Create a static Set with all valid values for this enum - f_enum << endl; + f_enum << '\n'; - indent(f_enum) << "static final Set VALID_VALUES = new Set.from([" << endl; + indent(f_enum) << "static final Set VALID_VALUES = new Set.from([" << '\n'; indent_up(); bool firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { // populate set indent(f_enum) << (firstValue ? "" : ", "); - f_enum << (*c_iter)->get_name() << endl; + f_enum << (*c_iter)->get_name() << '\n'; firstValue = false; } indent_down(); - indent(f_enum) << "]);" << endl; + indent(f_enum) << "]);" << '\n'; - indent(f_enum) << "static final Map VALUES_TO_NAMES = {" << endl; + indent(f_enum) << "static final Map VALUES_TO_NAMES = {" << '\n'; indent_up(); firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { indent(f_enum) << (firstValue ? "" : ", "); - f_enum << (*c_iter)->get_name() << ": '" << (*c_iter)->get_name() << "'" << endl; + f_enum << (*c_iter)->get_name() << ": '" << (*c_iter)->get_name() << "'" << '\n'; firstValue = false; } indent_down(); - indent(f_enum) << "};" << endl; + indent(f_enum) << "};" << '\n'; scope_down(f_enum); // end class @@ -545,8 +548,8 @@ void t_dart_generator::generate_consts(std::vector consts) { f_consts.open(f_consts_name.c_str()); // Print header - f_consts << autogen_comment() << dart_library(file_name) << endl; - f_consts << dart_thrift_imports() << endl; + f_consts << autogen_comment() << dart_library(file_name) << '\n'; + f_consts << dart_thrift_imports() << '\n'; export_class_to_library(file_name, class_name); indent(f_consts) << "class " << class_name; @@ -559,7 +562,7 @@ void t_dart_generator::generate_consts(std::vector consts) { (*c_iter)->get_type(), (*c_iter)->get_value(), false); - f_consts << endl; + f_consts << '\n'; } scope_down(f_consts); @@ -572,11 +575,12 @@ void t_dart_generator::print_const_value(std::ostream& out, t_type* type, t_const_value* value, bool in_static, - bool defval) { + bool defval, + bool inlineOnly) { type = get_true_type(type); indent(out); - if (!defval) { + if (!defval && !inlineOnly) { out << (in_static ? "var " : "static final "); } if (type->is_base_type()) { @@ -585,19 +589,23 @@ void t_dart_generator::print_const_value(std::ostream& out, } string v2 = render_const_value(out, name, type, value); out << name; - out << " = " << v2 << ";" << endl << endl; + out << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { if (!defval) { out << type_name(type) << " "; } out << name; - out << " = " << value->get_integer() << ";" << endl << endl; + out << " = " << value->get_integer() << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << type_name(type) << " " << name << " = new " << type_name(type) << "()"; + if (!inlineOnly) { + out << type_name(type) << " " << name << " = new " << type_name(type) << "()"; + } else { + out << "new " << type_name(type) << "()"; + } indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { t_type* field_type = nullptr; @@ -610,16 +618,24 @@ void t_dart_generator::print_const_value(std::ostream& out, throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } string val = render_const_value(out, name, field_type, v_iter->second); - out << endl; + out << '\n'; indent(out) << ".." << v_iter->first->get_string() << " = " << val; } indent_down(); - out << ";" << endl; + if (!inlineOnly) { + out << ";"; + } + out << '\n'; + } else if (type->is_map()) { - if (!defval) { + if (!defval && !inlineOnly) { out << type_name(type) << " "; } - out << name << " ="; + + if (!inlineOnly) { + out << name<< " ="; + } + scope_up(out); t_type* ktype = ((t_map*)type)->get_key_type(); @@ -630,22 +646,25 @@ void t_dart_generator::print_const_value(std::ostream& out, for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string key = render_const_value(out, name, ktype, v_iter->first); string val = render_const_value(out, name, vtype, v_iter->second); - indent(out) << key << ": " << val << "," << endl; + indent(out) << key << ": " << val << "," << '\n'; } - scope_down(out, ";" + endl); + scope_down(out, (inlineOnly? string("") : string(";")) + "\n"); - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { - if (!defval) { + if (!defval && !inlineOnly) { out << type_name(type) << " "; } - out << name << " = "; + if (!inlineOnly) { + out << name << " ="; + } + t_type* etype; if (type->is_list()) { - out << "[" << endl; + out << "[" << '\n'; etype = ((t_list*)type)->get_elem_type(); } else { - out << "new " << type_name(type) << ".from([" << endl; + out << "new " << type_name(type) << ".from([" << '\n'; etype = ((t_set*)type)->get_elem_type(); } const vector& val = value->get_list(); @@ -654,14 +673,14 @@ void t_dart_generator::print_const_value(std::ostream& out, indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, name, etype, *v_iter); - indent(out) << val << "," << endl; + indent(out) << val << "," << '\n'; } indent_down(); if (type->is_list()) { - indent(out) << "];" << endl; + indent(out) << "]" << (inlineOnly? "" : ";") << '\n'; } else { - indent(out) << "]);" << endl; + indent(out) << "])" << (inlineOnly? "" : ";") << '\n'; } } else { @@ -674,6 +693,7 @@ string t_dart_generator::render_const_value(ostream& out, t_type* type, t_const_value* value) { (void)name; + (void)out; type = get_true_type(type); std::ostringstream render; @@ -706,9 +726,7 @@ string t_dart_generator::render_const_value(ostream& out, render << value->get_integer(); } else { string t = tmp("tmp"); - print_const_value(out, t, type, value, true); - out << endl; - render << t; + print_const_value(render, t, type, value, true, false, true); } return render.str(); @@ -744,11 +762,11 @@ void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception ofstream_with_content_based_conditional_update f_struct; f_struct.open(f_struct_name.c_str()); - f_struct << autogen_comment() << dart_library(file_name) << endl; + f_struct << autogen_comment() << dart_library(file_name) << '\n'; string imports; - f_struct << dart_thrift_imports() << endl; + f_struct << dart_thrift_imports() << '\n'; generate_dart_struct_definition(f_struct, tstruct, is_exception, false, file_name); @@ -785,7 +803,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, scope_up(out); indent(out) << "static final TStruct _STRUCT_DESC = new TStruct(\"" << class_name - << "\");" << endl; + << "\");" << '\n'; // Members are public for -dart, private for -dartbean const vector& members = tstruct->get_members(); @@ -795,33 +813,33 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, indent(out) << "static final TField _" << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " << (*m_iter)->get_key() << ");" - << endl; + << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_dart_doc(out, *m_iter); - indent(out) << type_name((*m_iter)->get_type()) + " _" - << get_member_name((*m_iter)->get_name()) << init_value(*m_iter) << ";" << endl; + indent(out) << type_name((*m_iter)->get_type()) + get_type_suffix((*m_iter)->get_type()) + " _" + << get_member_name((*m_iter)->get_name()) << init_value(*m_iter) << ";" << '\n'; indent(out) << "static const int " << upcase_string((*m_iter)->get_name()) - << " = " << (*m_iter)->get_key() << ";" << endl; + << " = " << (*m_iter)->get_key() << ";" << '\n'; } - out << endl; + out << '\n'; // Inner Isset class if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { string field_name = get_member_name((*m_iter)->get_name()); - indent(out) << "bool __isset_" << field_name << " = false;" << endl; + indent(out) << "bool __isset_" << field_name << " = false;" << '\n'; } } } - out << endl; + out << '\n'; // Default constructor indent(out) << tstruct->get_name() << "()"; @@ -838,7 +856,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, } } scope_down(out); - out << endl; + out << '\n'; generate_dart_bean_boilerplate(out, tstruct); generate_generic_field_getters(out, tstruct); @@ -854,7 +872,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, generate_dart_struct_tostring(out, tstruct); generate_dart_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -870,20 +888,20 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - indent(out) << "TField field;" << endl; - indent(out) << "iprot.readStructBegin();" << endl; + indent(out) << "TField field;" << '\n'; + indent(out) << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields indent(out) << "while (true)"; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break indent(out) << "if (field.type == TType.STOP)"; scope_up(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; scope_down(out); // Switch statement on the field we are reading @@ -892,7 +910,7 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":" << endl; + indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ")"; @@ -903,33 +921,33 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru scope_down(out, " else"); scope_up(out); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; scope_down(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); } // In the default case we skip the field - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "break;" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "break;" << '\n'; indent_down(); scope_down(out); // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "iprot.readStructEnd();" << endl2; + indent(out) << "iprot.readStructEnd();" << '\n' << '\n'; // in non-beans style, check for required fields of primitive type // (which can be checked here but not in the general validate method) indent(out) << "// check for required fields of primitive type, which can't be " - "checked in the validate method" << endl; + "checked in the validate method" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { string field_name = get_member_name((*f_iter)->get_name()); @@ -937,15 +955,15 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru scope_up(out); indent(out) << " throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"Required field '" << field_name - << "' was not found in serialized data! Struct: \" + toString());" << endl; - scope_down(out, endl2); + << "' was not found in serialized data! Struct: \" + toString());" << '\n'; + scope_down(out, "\n\n"); } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } // generates dart method to perform various checks @@ -957,7 +975,7 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "// check for required fields" << endl; + indent(out) << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { string field_name = get_member_name((*f_iter)->get_name()); @@ -966,17 +984,17 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) scope_up(out); indent(out) << "throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"Required field '" << field_name << "' was not present! Struct: \" + toString());" - << endl; + << '\n'; scope_down(out); } else { indent(out) << "// alas, we cannot check '" << field_name - << "' because it's a primitive and you chose the non-beans generator." << endl; + << "' because it's a primitive and you chose the non-beans generator." << '\n'; } } } // check that fields of type enum have valid values - indent(out) << "// check that fields of type enum have valid values" << endl; + indent(out) << "// check that fields of type enum have valid values" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); t_type* type = field->get_type(); @@ -988,12 +1006,12 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) scope_up(out); indent(out) << "throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"The field '" << field_name << "' has been assigned the invalid value " - << "$" << field_name << "\");" << endl; + << "$" << field_name << "\");" << '\n'; scope_down(out); } } - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1009,9 +1027,9 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl2; + indent(out) << "validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_name = get_member_name((*f_iter)->get_name()); @@ -1027,13 +1045,13 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru } indent(out) << "oprot.writeFieldBegin(_" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (null_allowed) { scope_down(out); @@ -1043,10 +1061,10 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru } } // Write the struct map - indent(out) << "oprot.writeFieldStop();" << endl << indent() << "oprot.writeStructEnd();" - << endl; + indent(out) << "oprot.writeFieldStop();" << '\n' << indent() << "oprot.writeStructEnd();" + << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1064,7 +1082,7 @@ void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << endl2; + indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << '\n' << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1079,23 +1097,23 @@ void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct scope_up(out); indent(out) << "oprot.writeFieldBegin(_" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; scope_down(out, ""); } - out << endl; + out << '\n'; // Write the struct map - indent(out) << "oprot.writeFieldStop();" << endl << indent() - << "oprot.writeStructEnd();" << endl; + indent(out) << "oprot.writeFieldStop();" << '\n' << indent() + << "oprot.writeStructEnd();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } void t_dart_generator::generate_generic_field_getters(std::ostream& out, @@ -1113,26 +1131,26 @@ void t_dart_generator::generate_generic_field_getters(std::ostream& out, t_field* field = *f_iter; std::string field_name = get_member_name(field->get_name()); - indent(out) << "case " << upcase_string(field_name) << ":" << endl; + indent(out) << "case " << upcase_string(field_name) << ":" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } void t_dart_generator::generate_generic_field_setters(std::ostream& out, t_struct* tstruct) { // create the setter - indent(out) << "setFieldValue(int fieldID, Object value)"; + indent(out) << "setFieldValue(int fieldID, Object? value)"; scope_up(out); indent(out) << "switch (fieldID)"; @@ -1143,33 +1161,35 @@ void t_dart_generator::generate_generic_field_setters(std::ostream& out, vector::const_iterator f_iter; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; + t_type* type = get_true_type(field->get_type()); std::string field_name = get_member_name(field->get_name()); - indent(out) << "case " << upcase_string(field_name) << ":" << endl; + indent(out) << "case " << upcase_string(field_name) << ":" << '\n'; indent_up(); indent(out) << "if (value == null)"; scope_up(out); - indent(out) << "unset" << get_cap_name(field_name) << "();" << endl; + indent(out) << "unset" << get_cap_name(field_name) << "();" << '\n'; scope_down(out, " else"); scope_up(out); - indent(out) << "this." << field_name << " = value;" << endl; + + indent(out) << "this." << field_name << " = value as " << type_name(type) << ";" << '\n'; scope_down(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - out << endl; + out << '\n'; } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } // Creates a generic isSet method that takes the field number as argument @@ -1179,7 +1199,7 @@ void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "// Returns true if field corresponding to fieldID is set (has been assigned a " - "value) and false otherwise" << endl; + "value) and false otherwise" << '\n'; indent(out) << "bool isSet(int fieldID)"; scope_up(out); @@ -1188,19 +1208,19 @@ void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << upcase_string(field->get_name()) << ":" << endl; + indent(out) << "case " << upcase_string(field->get_name()) << ":" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } /** @@ -1219,37 +1239,37 @@ void t_dart_generator::generate_dart_bean_boilerplate(ostream& out, std::string field_name = get_member_name(field->get_name()); std::string cap_name = get_cap_name(field_name); - indent(out) << "// " << field_name << endl; + indent(out) << "// " << field_name << '\n'; // Simple getter generate_dart_doc(out, field); - indent(out) << type_name(type) << " get " << field_name << " => this._" << field_name << ";" << endl2; + indent(out) << type_name(type) << get_type_suffix(type) << " get " << field_name << " => this._" << field_name << ";" << '\n' << '\n'; // Simple setter generate_dart_doc(out, field); - indent(out) << "set " << field_name << "(" << type_name(type) << " " << field_name << ")"; + indent(out) << "set " << field_name << "(" << type_name(type) << get_type_suffix(type) << " " << field_name << ")"; scope_up(out); - indent(out) << "this._" << field_name << " = " << field_name << ";" << endl; + indent(out) << "this._" << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); - scope_down(out, endl2); + scope_down(out, "\n\n"); // isSet method indent(out) << "bool is" << get_cap_name("set") << cap_name << "()"; if (type_can_be_null(type)) { - out << " => this." << field_name << " != null;" << endl2; + out << " => this." << field_name << " != null;" << '\n' << '\n'; } else { - out << " => this.__isset_" << field_name << ";" << endl2; + out << " => this.__isset_" << field_name << ";" << '\n' << '\n'; } // Unsetter indent(out) << "unset" << cap_name << "()"; scope_up(out); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "this.__isset_" << field_name << " = false;" << endl; + indent(out) << "this.__isset_" << field_name << " = false;" << '\n'; } - scope_down(out, endl2); + scope_down(out, "\n\n"); } } @@ -1264,7 +1284,7 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, scope_up(out); indent(out) << "StringBuffer ret = new StringBuffer(\"" - << tstruct->get_name() << "(\");" << endl2; + << tstruct->get_name() << "(\");" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1281,36 +1301,36 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, std::string field_name = get_member_name(field->get_name()); if (!first) { - indent(out) << "ret.write(\", \");" << endl; + indent(out) << "ret.write(\", \");" << '\n'; } - indent(out) << "ret.write(\"" << field_name << ":\");" << endl; + indent(out) << "ret.write(\"" << field_name << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { indent(out) << "if (this." << field_name << " == null)"; scope_up(out); - indent(out) << "ret.write(\"null\");" << endl; + indent(out) << "ret.write(\"null\");" << '\n'; scope_down(out, " else"); scope_up(out); } if (field->get_type()->is_binary()) { - indent(out) << "ret.write(\"BINARY\");" << endl; + indent(out) << "ret.write(\"BINARY\");" << '\n'; } else if (field->get_type()->is_enum()) { - indent(out) << "String " << field_name << "_name = " + indent(out) << "String? " << field_name << "_name = " << get_ttype_class_name(field->get_type()) - << ".VALUES_TO_NAMES[this." << field_name << "];" << endl; + << ".VALUES_TO_NAMES[this." << field_name << "];" << '\n'; indent(out) << "if (" << field_name << "_name != null)"; scope_up(out); - indent(out) << "ret.write(" << field_name << "_name);" << endl; - indent(out) << "ret.write(\" (\");" << endl; + indent(out) << "ret.write(" << field_name << "_name);" << '\n'; + indent(out) << "ret.write(\" (\");" << '\n'; scope_down(out); - indent(out) << "ret.write(this." << field_name << ");" << endl; + indent(out) << "ret.write(this." << field_name << ");" << '\n'; indent(out) << "if (" << field_name << "_name != null)"; scope_up(out); - indent(out) << "ret.write(\")\");" << endl; + indent(out) << "ret.write(\")\");" << '\n'; scope_down(out); } else { - indent(out) << "ret.write(this." << field_name << ");" << endl; + indent(out) << "ret.write(this." << field_name << ");" << '\n'; } if (can_be_null) { @@ -1320,15 +1340,15 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, scope_down(out); } - out << endl; + out << '\n'; first = false; } - indent(out) << "ret.write(\")\");" << endl2; + indent(out) << "ret.write(\")\");" << '\n' << '\n'; - indent(out) << "return ret.toString();" << endl; + indent(out) << "return ret.toString();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1391,9 +1411,9 @@ void t_dart_generator::generate_service(t_service* tservice) { string f_service_name = src_dir_ + "/" + file_name + ".dart"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << dart_library(file_name) << endl; - f_service_ << service_imports() << dart_thrift_imports() << endl; - f_service_ << endl; + f_service_ << autogen_comment() << dart_library(file_name) << '\n'; + f_service_ << service_imports() << dart_thrift_imports() << '\n'; + f_service_ << '\n'; generate_service_interface(tservice); generate_service_client(tservice); @@ -1424,12 +1444,12 @@ void t_dart_generator::generate_service_interface(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << endl; + f_service_ << '\n'; generate_dart_doc(f_service_, *f_iter); - indent(f_service_) << function_signature(*f_iter) << ";" << endl; + indent(f_service_) << function_signature(*f_iter) << ";" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1465,31 +1485,31 @@ void t_dart_generator::generate_service_client(t_service* tservice) { indent(f_service_) << "class " << class_name << extends_client << " implements " << service_name_; scope_up(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << class_name << "(TProtocol iprot, [TProtocol oprot = null])"; + indent(f_service_) << class_name << "(TProtocol iprot, [TProtocol? oprot = null])"; if (!extends.empty()) { indent_up(); - f_service_ << endl; - indent(f_service_) << ": super(iprot, oprot);" << endl; + f_service_ << '\n'; + indent(f_service_) << ": super(iprot, oprot);" << '\n'; indent_down(); } else { scope_up(f_service_); - indent(f_service_) << "_iprot = iprot;" << endl; - indent(f_service_) << "_oprot = (oprot == null) ? iprot : oprot;" << endl; + indent(f_service_) << "_iprot = iprot;" << '\n'; + indent(f_service_) << "_oprot = (oprot == null) ? iprot : oprot;" << '\n'; scope_down(f_service_); } - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - indent(f_service_) << "TProtocol _iprot;" << endl2; - indent(f_service_) << "TProtocol get iprot => _iprot;" << endl2; - indent(f_service_) << "TProtocol _oprot;" << endl2; - indent(f_service_) << "TProtocol get oprot => _oprot;" << endl2; - indent(f_service_) << "int _seqid = 0;" << endl2; - indent(f_service_) << "int get seqid => _seqid;" << endl2; - indent(f_service_) << "int nextSeqid() => ++_seqid;" << endl2; + indent(f_service_) << "late TProtocol _iprot;" << '\n' << '\n'; + indent(f_service_) << "TProtocol get iprot => _iprot;" << '\n' << '\n'; + indent(f_service_) << "late TProtocol _oprot;" << '\n' << '\n'; + indent(f_service_) << "TProtocol get oprot => _oprot;" << '\n' << '\n'; + indent(f_service_) << "int _seqid = 0;" << '\n' << '\n'; + indent(f_service_) << "int get seqid => _seqid;" << '\n' << '\n'; + indent(f_service_) << "int nextSeqid() => ++_seqid;" << '\n' << '\n'; } // Generate client method implementations @@ -1510,40 +1530,40 @@ void t_dart_generator::generate_service_client(t_service* tservice) { // Serialize the request indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << (*f_iter)->get_name() << "\", " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", nextSeqid()));" << endl; - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; + << ", nextSeqid()));" << '\n'; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { string arg_field_name = get_member_name((*fld_iter)->get_name()); indent(f_service_) << "args." << arg_field_name << " = " - << arg_field_name << ";" << endl; + << arg_field_name << ";" << '\n'; } - indent(f_service_) << "args.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl2; + indent(f_service_) << "args.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n' << '\n'; - indent(f_service_) << "await oprot.transport.flush();" << endl2; + indent(f_service_) << "await oprot.transport.flush();" << '\n' << '\n'; if (!(*f_iter)->is_oneway()) { - indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << endl; + indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << '\n'; indent(f_service_) << "if (msg.type == TMessageType.EXCEPTION)"; scope_up(f_service_); - indent(f_service_) << "TApplicationError error = TApplicationError.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; - indent(f_service_) << "throw error;" << endl; - scope_down(f_service_, endl2); + indent(f_service_) << "TApplicationError error = TApplicationError.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; + indent(f_service_) << "throw error;" << '\n'; + scope_down(f_service_, "\n\n"); string result_class = get_result_class_name((*f_iter)->get_name()); - indent(f_service_) << result_class << " result = new " << result_class << "();" << endl; - indent(f_service_) << "result.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << result_class << " result = new " << result_class << "();" << '\n'; + indent(f_service_) << "result.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { indent(f_service_) << "if (result." << generate_isset_check("success") << ")"; scope_up(f_service_); - indent(f_service_) << "return result.success;" << endl; - scope_down(f_service_, endl2); + indent(f_service_) << "return result.success;" << '\n'; + scope_down(f_service_, "\n\n"); } t_struct* xs = (*f_iter)->get_xceptions(); @@ -1553,23 +1573,23 @@ void t_dart_generator::generate_service_client(t_service* tservice) { string result_field_name = get_member_name((*x_iter)->get_name()); indent(f_service_) << "if (result." << result_field_name << " != null)"; scope_up(f_service_); - indent(f_service_) << "throw result." << result_field_name << ";" << endl; + indent(f_service_) << "throw result." << result_field_name << "!;" << '\n'; scope_down(f_service_); } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << "throw new TApplicationError(TApplicationErrorType.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1583,14 +1603,16 @@ void t_dart_generator::generate_service_server(t_service* tservice) { vector::iterator f_iter; // typedef - indent(f_service_) << "typedef void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);" << endl2; + indent(f_service_) << "typedef void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);" << '\n' << '\n'; // Extends stuff string extends = ""; string extends_processor = ""; + string extends_covariant = ""; if (tservice->get_extends() != nullptr) { extends = get_ttype_class_name(tservice->get_extends()); extends_processor = " extends " + extends + "Processor"; + extends_covariant = "covariant "; } // Generate the header portion @@ -1602,57 +1624,58 @@ void t_dart_generator::generate_service_server(t_service* tservice) { indent(f_service_) << class_name << "(" << service_name_ << " iface)"; if (!extends.empty()) { indent_up(); - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << ": super(iface)"; indent_down(); } scope_up(f_service_); if (extends.empty()) { - indent(f_service_) << "iface_ = iface;" << endl; + indent(f_service_) << "iface_ = iface;" << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "PROCESS_MAP[\"" << (*f_iter)->get_name() - << "\"] = " << get_member_name((*f_iter)->get_name()) << ";" << endl; + << "\"] = " << get_member_name((*f_iter)->get_name()) << ";" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); + - indent(f_service_) << service_name_ << " iface_;" << endl; + indent(f_service_) << extends_covariant << "late " << service_name_ << " iface_;" << '\n'; if (extends.empty()) { - indent(f_service_) << "final Map PROCESS_MAP = {};" << endl; + indent(f_service_) << "final Map PROCESS_MAP = {};" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation indent(f_service_) << "bool process(TProtocol iprot, TProtocol oprot)"; scope_up(f_service_); - indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << endl; - indent(f_service_) << "ProcessFunction fn = PROCESS_MAP[msg.name];" << endl; + indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << '\n'; + indent(f_service_) << "ProcessFunction? fn = PROCESS_MAP[msg.name];" << '\n'; indent(f_service_) << "if (fn == null)"; scope_up(f_service_); - indent(f_service_) << "TProtocolUtil.skip(iprot, TType.STRUCT);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << "TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; indent(f_service_) << "TApplicationError x = new TApplicationError(TApplicationErrorType.UNKNOWN_METHOD, " - "\"Invalid method name: '\"+msg.name+\"'\");" << endl; - indent(f_service_) << "oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl; - indent(f_service_) << "x.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; - indent(f_service_) << "return true;" << endl; + "\"Invalid method name: '\"+msg.name+\"'\");" << '\n'; + indent(f_service_) << "oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << '\n'; + indent(f_service_) << "x.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; + indent(f_service_) << "return true;" << '\n'; scope_down(f_service_); - indent(f_service_) << "fn(msg.seqid, iprot, oprot);" << endl; - indent(f_service_) << "return true;" << endl; - scope_down(f_service_, endl2); // process function + indent(f_service_) << "fn(msg.seqid, iprot, oprot);" << '\n'; + indent(f_service_) << "return true;" << '\n'; + scope_down(f_service_, "\n\n"); // process function // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } - scope_down(f_service_, endl2); // class + scope_down(f_service_, "\n\n"); // class } /** @@ -1700,16 +1723,16 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function string argsname = get_args_class_name(tfunction->get_name()); string resultname = get_result_class_name(tfunction->get_name()); - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; - indent(f_service_) << "args.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; + indent(f_service_) << "args.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -1736,7 +1759,7 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << get_member_name((*f_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { @@ -1747,36 +1770,36 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function scope_up(f_service_); if (!tfunction->is_oneway()) { indent(f_service_) << "result." << result_field_name << " = " - << result_field_name << ";" << endl; + << result_field_name << ";" << '\n'; } } scope_down(f_service_, " "); f_service_ << "catch (th)"; scope_up(f_service_); - indent(f_service_) << "// Internal error" << endl; + indent(f_service_) << "// Internal error" << '\n'; indent(f_service_) << "TApplicationError x = new " "TApplicationError(TApplicationErrorType.INTERNAL_ERROR, \"Internal error processing " - << tfunction->get_name() << "\");" << endl; + << tfunction->get_name() << "\");" << '\n'; indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.EXCEPTION, seqid));" << endl; - indent(f_service_) << "x.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; - indent(f_service_) << "return;" << endl; + << "\", TMessageType.EXCEPTION, seqid));" << '\n'; + indent(f_service_) << "x.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; + indent(f_service_) << "return;" << '\n'; scope_down(f_service_); } if (tfunction->is_oneway()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl; - indent(f_service_) << "result.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n'; + indent(f_service_) << "result.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1840,7 +1863,7 @@ void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "readI32();"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", field_name.c_str(), @@ -1852,8 +1875,8 @@ void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, * Generates an unserializer for a struct, invokes read() */ void t_dart_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl; - indent(out) << prefix << ".read(iprot);" << endl; + indent(out) << prefix << " = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << prefix << "!.read(iprot);" << '\n'; } /** @@ -1875,14 +1898,14 @@ void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Declare variables, read header if (ttype->is_map()) { - indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "TList " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "TList " << obj << " = iprot.readListBegin();" << '\n'; } - indent(out) << prefix << " = new " << type_name(ttype) << "();" << endl; + indent(out) << prefix << " = " << type_name_instantiate(ttype) << ";" << '\n'; // For loop iterates over elements string i = tmp("_i"); @@ -1903,11 +1926,11 @@ void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -1922,13 +1945,13 @@ void t_dart_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << "[" << key << "] = " << val << ";" << endl; + indent(out) << prefix << "![" << key << "] = " << val << ";" << '\n'; } /** @@ -1938,11 +1961,11 @@ void t_dart_generator::generate_deserialize_set_element(ostream& out, t_set* tse string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << "!.add(" << elem << ");" << '\n'; } /** @@ -1954,11 +1977,11 @@ void t_dart_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << "!.add(" << elem << ");" << '\n'; } /** @@ -1970,6 +1993,7 @@ void t_dart_generator::generate_deserialize_list_element(ostream& out, void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) { t_type* type = get_true_type(tfield->get_type()); string field_name = get_member_name(tfield->get_name()); + bool null_allowed = type_can_be_null(type); // Do nothing for void types if (type->is_void()) { @@ -1993,28 +2017,28 @@ void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, s break; case t_base_type::TYPE_STRING: if (type->is_binary()) { - out << "writeBinary(" << name << ");"; + out << "writeBinary(" << name << (null_allowed ? "!);" : ");"); } else { - out << "writeString(" << name << ");"; + out << "writeString(" << name << (null_allowed ? "!);" : ");"); } break; case t_base_type::TYPE_BOOL: - out << "writeBool(" << name << ");"; + out << "writeBool(" << name << "!);"; break; case t_base_type::TYPE_I8: - out << "writeByte(" << name << ");"; + out << "writeByte(" << name << "!);"; break; case t_base_type::TYPE_I16: - out << "writeI16(" << name << ");"; + out << "writeI16(" << name << "!);"; break; case t_base_type::TYPE_I32: - out << "writeI32(" << name << ");"; + out << "writeI32(" << name << "!);"; break; case t_base_type::TYPE_I64: - out << "writeI64(" << name << ");"; + out << "writeI64(" << name << "!);"; break; case t_base_type::TYPE_DOUBLE: - out << "writeDouble(" << name << ");"; + out << "writeDouble(" << name << "!);"; break; default: throw "compiler error: no Dart name for base type " + t_base_type::t_base_name(tbase); @@ -2022,7 +2046,7 @@ void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2039,7 +2063,7 @@ void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_dart_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(oprot);" << endl; + indent(out) << prefix << "?.write(oprot);" << '\n'; } /** @@ -2055,22 +2079,22 @@ void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { string iter = tmp("_key"); indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) - << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix << ".length));" - << endl; + << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix << "!.length));" + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".length));" << endl; + << ", " << prefix << "!.length));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" - << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".length));" - << endl; + << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << "!.length));" + << '\n'; } string iter = tmp("elem"); if (ttype->is_map()) { - indent(out) << "for (var " << iter << " in " << prefix << ".keys)"; + indent(out) << "for (var " << iter << " in " << prefix << "!.keys)"; } else if (ttype->is_set() || ttype->is_list()) { - indent(out) << "for (var " << iter << " in " << prefix << ")"; + indent(out) << "for (var " << iter << " in " << prefix << "!)"; } scope_up(out); @@ -2086,11 +2110,11 @@ void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } scope_down(out); @@ -2105,7 +2129,7 @@ void t_dart_generator::generate_serialize_map_element(ostream& out, string map) { t_field kfield(tmap->get_key_type(), iter); generate_serialize_field(out, &kfield, ""); - t_field vfield(tmap->get_val_type(), map + "[" + iter + "]"); + t_field vfield(tmap->get_val_type(), map + "![" + iter + "]"); generate_serialize_field(out, &vfield, ""); } @@ -2153,6 +2177,34 @@ string t_dart_generator::type_name(t_type* ttype) { return get_ttype_class_name(ttype); } +/** + * Returns instantiate code for a Dart type name + * + * @param ttype The type + * @return Dart type name, i.e. Map + */ +string t_dart_generator::type_name_instantiate(t_type* ttype) { + ttype = get_true_type(ttype); + + if (ttype->is_base_type()) { + return base_type_name((t_base_type*)ttype); + } else if (ttype->is_enum()) { + return "int"; + } else if (ttype->is_map()) { + t_map* tmap = (t_map*)ttype; + return "<" + type_name(tmap->get_key_type()) + ", " + + type_name(tmap->get_val_type()) + ">{}"; + } else if (ttype->is_set()) { + t_set* tset = (t_set*)ttype; + return "<" + type_name(tset->get_elem_type()) + ">{}"; + } else if (ttype->is_list()) { + t_list* tlist = (t_list*)ttype; + return "<" + type_name(tlist->get_elem_type()) + ">[]"; + } + + return get_ttype_class_name(ttype); +} + /** * Returns the Dart type that corresponds to the thrift type. * @@ -2244,9 +2296,9 @@ string t_dart_generator::function_signature(t_function* tfunction) { std::string returntype; if (tfunction->get_returntype()->is_void()) { - returntype = "Future"; + returntype = "Future"; } else { - returntype = "Future<" + type_name(tfunction->get_returntype()) + ">"; + returntype = "Future<" + type_name(tfunction->get_returntype()) + get_type_suffix(tfunction->get_returntype()) + ">"; } std::string result = returntype + " " + get_member_name(tfunction->get_name()) + @@ -2270,7 +2322,7 @@ string t_dart_generator::argument_list(t_struct* tstruct) { result += ", "; } string field_name = get_member_name((*f_iter)->get_name()); - result += type_name((*f_iter)->get_type()) + " " + field_name; + result += type_name((*f_iter)->get_type()) + (type_can_be_null((*f_iter)->get_type()) ? "?" : "") + " " + field_name; } return result; } @@ -2319,13 +2371,14 @@ string t_dart_generator::type_to_enum(t_type* type) { } std::string t_dart_generator::init_value(t_field* field) { - // Do not initialize optional fields - if (field->get_req() == t_field::T_OPTIONAL) { - return ""; - } t_type* ttype = field->get_type(); + if (ttype->is_enum()) + { + return " = 0"; + } + // Get the actual type for a typedef if (ttype->is_typedef()) { ttype = ((t_typedef*)ttype)->get_type(); @@ -2496,7 +2549,7 @@ std::string t_dart_generator::generate_isset_check(std::string field_name) { void t_dart_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { string field_name = get_member_name(field->get_name()); - indent(out) << "this.__isset_" << field_name << " = true;" << endl; + indent(out) << "this.__isset_" << field_name << " = true;" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc index c91ff332eab..cc6a460aded 100644 --- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc @@ -53,8 +53,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - class t_delphi_generator : public t_oop_generator { public: t_delphi_generator(t_program* program, @@ -68,7 +66,6 @@ class t_delphi_generator : public t_oop_generator { has_const = false; std::map::const_iterator iter; - ansistr_binary_ = false; register_types_ = false; constprefix_ = false; old_names_ = false; @@ -78,10 +75,7 @@ class t_delphi_generator : public t_oop_generator { com_types_ = false; rtti_ = false; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { - if( iter->first.compare("ansistr_binary") == 0) { - ansistr_binary_ = true; - pwarning(0, "The 'ansistr_binary' option is deprecated."); - } else if( iter->first.compare("register_types") == 0) { + if( iter->first.compare("register_types") == 0) { register_types_ = true; } else if( iter->first.compare("old_names") == 0) { old_names_ = true; @@ -102,10 +96,6 @@ class t_delphi_generator : public t_oop_generator { } } - if(com_types_ && ansistr_binary_) { - throw "com_types and ansistr_binary are mutually exclusive"; - } - out_dir_base_ = "gen-delphi"; escape_.clear(); escape_['\''] = "''"; @@ -124,13 +114,11 @@ class t_delphi_generator : public t_oop_generator { void generate_xception(t_struct* txception) override; void generate_service(t_service* tservice) override; void generate_property(ostream& out, t_field* tfield, bool isPublic, bool is_xception); - void generate_property_writer_(ostream& out, t_field* tfield, bool isPublic); void generate_delphi_property(ostream& out, bool struct_is_exception, t_field* tfield, - bool isPublic, - std::string fieldPrefix = ""); + bool isPublic); void generate_delphi_isset_reader_writer_definition(ostream& out, t_field* tfield, bool is_xception); void generate_delphi_property_reader_definition(ostream& out, t_field* tfield, @@ -152,9 +140,7 @@ class t_delphi_generator : public t_oop_generator { t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name); + bool is_union); void generate_delphi_clear_union_value(ostream& out, std::string cls_prefix, std::string name, @@ -162,44 +148,33 @@ class t_delphi_generator : public t_oop_generator { t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name); + bool is_union); void generate_delphi_isset_reader_writer_impl(ostream& out, - std::string cls_prefix, - std::string name, - t_type* type, - t_field* tfield, - std::string fieldPrefix, - bool is_xception); + std::string cls_prefix, + std::string name, + t_type* type, + t_field* tfield, + std::string fieldPrefix, + bool is_xception_class); void generate_delphi_struct_writer_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); - void generate_delphi_struct_result_writer_impl(ostream& out, - std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_x_factory); + bool is_exception); void generate_delphi_struct_tostring_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); + bool is_exception); void add_delphi_uses_list(string unitname); void generate_delphi_struct_reader_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); - void generate_delphi_create_exception_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception); + bool is_exception); + + bool is_deprecated(std::map>& annotations); + std::string render_deprecation_attribute(std::map>& annotations, std::string prefix, std::string postfix); bool const_needs_var(t_type* type); void print_const_prop(std::ostream& out, string name, t_type* type, t_const_value* value); @@ -208,12 +183,14 @@ class t_delphi_generator : public t_oop_generator { std::ostream& out, std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool is_const_class); void initialize_field(std::ostream& vars, std::ostream& out, std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool is_const_class); void finalize_field(std::ostream& out, std::string name, t_type* type, @@ -221,9 +198,9 @@ class t_delphi_generator : public t_oop_generator { std::string cls_nm = ""); std::string render_const_value(std::ostream& local_vars, std::ostream& out, - std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool guidAsLiteral); void print_const_def_value(std::ostream& vars, std::ostream& out, std::string name, @@ -232,36 +209,27 @@ class t_delphi_generator : public t_oop_generator { std::string cls_nm = ""); std::string make_constants_classname(); - void generate_delphi_struct(t_struct* tstruct, bool is_exception); + void generate_delphi_struct(t_struct* tstruct); + void generate_delphi_exception(t_struct* tstruct); void generate_delphi_struct_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + bool is_result, + bool is_const_class); + void generate_delphi_exception_impl(ostream& out, + std::string cls_prefix, + t_struct* tstruct); void print_delphi_struct_type_factory_func(ostream& out, t_struct* tstruct); void generate_delphi_struct_type_factory(ostream& out, std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + t_struct* tstruct); void generate_delphi_struct_type_factory_registration(ostream& out, std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + t_struct* tstruct); void generate_delphi_struct_definition(std::ostream& out, - t_struct* tstruct, - bool is_xception = false, - bool in_class = false, - bool is_result = false, - bool is_x_factory = false); - void generate_delphi_struct_reader(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_result_writer(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_writer(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_tostring(std::ostream& out, t_struct* tstruct); + t_struct* tstruct); + void generate_delphi_exception_definition(std::ostream& out, + t_struct* tstruct); void generate_function_helpers(t_function* tfunction); void generate_service_interface(t_service* tservice); @@ -335,13 +303,10 @@ class t_delphi_generator : public t_oop_generator { std::ostream& local_vars); void delphi_type_usings(std::ostream& out); - std::string delphi_thrift_usings(); std::string type_name(t_type* ttype, bool b_cls = false, - bool b_no_postfix = false, - bool b_exception_factory = false, - bool b_full_exception_factory = false); + bool b_no_postfix = false); std::string normalize_clsnm(std::string name, std::string prefix, bool b_no_check_keyword = false); @@ -351,7 +316,6 @@ class t_delphi_generator : public t_oop_generator { std::string base_type_name(t_base_type* tbase); std::string declare_field(t_field* tfield, - bool init = false, std::string prefix = "", bool is_xception_class = false); std::string function_signature(t_function* tfunction, @@ -365,12 +329,6 @@ class t_delphi_generator : public t_oop_generator { std::string prop_name(std::string name, bool is_xception = false, std::string prefix = ""); std::string constructor_param_name(string name); - void write_enum(std::string line); - void write_forward_decr(std::string line); - void write_const(std::string line); - void write_struct(std::string line); - void write_service(std::string line); - std::string autogen_comment() override { return std::string("(**\n") + " * Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n" + " *\n" + " * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" @@ -387,10 +345,7 @@ class t_delphi_generator : public t_oop_generator { void generate_delphi_docstring_comment(std::ostream& out, string contents); bool type_can_be_null(t_type* ttype) { - while (ttype->is_typedef()) { - ttype = ((t_typedef*)ttype)->get_type(); - } - + ttype = ttype->get_true_type(); return ttype->is_container() || ttype->is_struct() || ttype->is_xception(); } @@ -417,37 +372,38 @@ class t_delphi_generator : public t_oop_generator { const std::string DELPHI_KEYWORDS[81] = { // keywords - "and", "array", "as", "asm", "at", "automated", "begin", "case", "class", "const", "constructor", - "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", - "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", - "initialization", "inline", "interface", "is", "label", "library", "mod", "nil", "not", "object", - "of", "on", "or", "out", "packed", "private", "procedure", "program", "property", "protected", - "public", "published", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", + "and", "array", "as", "asm", "at", "automated", "begin", "case", "class", "const", "constructor", + "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", + "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", + "initialization", "inline", "interface", "is", "label", "library", "mod", "nil", "not", "object", + "of", "on", "or", "out", "packed", "private", "procedure", "program", "property", "protected", + "public", "published", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", "then", "threadvar", "to", "try", "type", "unit", "until", "uses", "var", "while", "with", "xor", // predefined types (lowercase!) "ansistring", "boolean", "double", "int64", "integer", "shortint", "smallint", "string", "unicodestring" }; // reserved variables and types (lowercase!) - const std::string DELPHI_RESERVED_NAMES[8] = { - "result", "system", "sysutils", "tbytes", "tclass", "thrift", "tinterfacedobject", "tobject" + const std::string DELPHI_RESERVED_NAMES[11] = { + "result", "system", "sysutils", "types", "texception", "tbytes", "tclass", "thrift", "tinterfacedobject", + "tobject", "ttask" }; // reserved method names (lowercase!) const std::string DELPHI_RESERVED_METHOD[31] = { - "afterconstruction", "beforedestruction", "classinfo", "classname", "classnameis", "classparent", - "classtype", "cleanupinstance", "create", "defaulthandler", "destroy", "dispatch", "equals", - "fieldaddress", "free", "freeinstance", "gethashcode", "getinterface", "getinterfaceentry", - "getinterfacetable", "inheritsfrom", "initinstance", "instancesize", "methodaddress", "methodname", + "afterconstruction", "beforedestruction", "classinfo", "classname", "classnameis", "classparent", + "classtype", "cleanupinstance", "create", "defaulthandler", "destroy", "dispatch", "equals", + "fieldaddress", "free", "freeinstance", "gethashcode", "getinterface", "getinterfaceentry", + "getinterfacetable", "inheritsfrom", "initinstance", "instancesize", "methodaddress", "methodname", "newinstance", "read", "safecallexception", "tostring", "unitname", "write" }; // reserved exception class method names (lowercase!) - const std::string DELPHI_RESERVED_METHOD_EXCEPTION[23] = { - "setinnerexception", "setstackinfo", "getstacktrace", "raisingexception", "createfmt", "createres", - "createresfmt", "createhelp", "createfmthelp", "createreshelp", "createresfmthelp", "getbaseexception", - "baseexception", "helpcontext", "innerexception", "message", "stacktrace", "stackinfo", - "getexceptionstackinfoproc", "getstackinfostringproc", "cleanupstackinfoproc", "raiseouterexception", + const std::string DELPHI_RESERVED_METHOD_EXCEPTION[24] = { + "setinnerexception", "setstackinfo", "getstacktrace", "raisingexception", "createfmt", "createres", + "createresfmt", "createhelp", "createfmthelp", "createreshelp", "createresfmthelp", "getbaseexception", + "baseexception", "helpcontext", "innerexception", "exceptiondata", "message", "stacktrace", "stackinfo", + "getexceptionstackinfoproc", "getstackinfostringproc", "cleanupstackinfoproc", "raiseouterexception", "throwouterexception" }; @@ -468,7 +424,6 @@ class t_delphi_generator : public t_oop_generator { void init_known_types_list(); bool is_void(t_type* type); int indent_impl_; - bool ansistr_binary_; bool register_types_; bool constprefix_; bool old_names_; @@ -637,10 +592,10 @@ std::string t_delphi_generator::normalize_name(std::string name, } // neither reserved nor keyword? - if (!(b_reserved || b_keyword)) { + if (!(b_reserved || b_keyword)) { return name; } - + // apply the rule: old style '_' postfix or more modern '&' prefix? // underscore always on non-keywords or when explicitly asked via arg if( (!b_keyword) || old_names_ || b_force_underscore) { @@ -695,8 +650,9 @@ void t_delphi_generator::init_generator() { unitname = include->get_name(); nsname = include->get_namespace("delphi"); if ("" != nsname) { - unitname = normalize_name(nsname,false,false,true/*force underscore*/); + unitname = nsname; } + unitname = normalize_name(unitname,false,false,true/*force underscore*/); add_delphi_uses_list(unitname); } @@ -716,25 +672,25 @@ void t_delphi_generator::close_generator() { } unitname = normalize_name(unitname,false,false,true/*force underscore*/); - + std::string f_name = get_out_dir() + "/" + unitname + ".pas"; ofstream_with_content_based_conditional_update f_all; f_all.open(f_name); - f_all << autogen_comment() << endl; + f_all << autogen_comment() << '\n'; generate_delphi_doc(f_all, program_); - f_all << "unit " << unitname << ";" << endl << endl; - f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << endl; + f_all << "unit " << unitname << ";" << '\n' << '\n'; + f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << '\n'; if(com_types_) { - f_all << "{$MINENUMSIZE 4}" << endl; + f_all << "{$MINENUMSIZE 4}" << '\n'; } if(rtti_) { - f_all << "{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}" << endl; + f_all << "{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}" << '\n'; } - f_all << endl; - f_all << "interface" << endl << endl; - f_all << "uses" << endl; + f_all << '\n'; + f_all << "interface" << '\n' << '\n'; + f_all << "uses" << '\n'; indent_up(); @@ -742,12 +698,12 @@ void t_delphi_generator::close_generator() { for (s_iter = uses_list.begin(); s_iter != uses_list.end(); ++s_iter) { if (s_iter != uses_list.begin()) { f_all << ","; - f_all << endl; + f_all << '\n'; } indent(f_all) << *s_iter; } - f_all << ";" << endl << endl; + f_all << ";" << '\n' << '\n'; indent_down(); @@ -758,71 +714,70 @@ void t_delphi_generator::close_generator() { } } - f_all << "const" << endl; + f_all << "const" << '\n'; indent_up(); - indent(f_all) << "c" << tmp_unit << "_Option_AnsiStr_Binary = " << (ansistr_binary_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Register_Types = " << (register_types_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_ConstPrefix = " << (constprefix_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Events = " << (events_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << (xmldoc_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Async = " << (async_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_COM_types = " << (com_types_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Old_Names = " << (old_names_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_RTTI = " << (rtti_ ? "True" : "False") << ";" << endl; + indent(f_all) << "c" << tmp_unit << "_Option_Register_Types = " << (register_types_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_ConstPrefix = " << (constprefix_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Events = " << (events_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << (xmldoc_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Async = " << (async_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_COM_types = " << (com_types_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Old_Names = " << (old_names_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_RTTI = " << (rtti_ ? "True" : "False") << ";" << '\n'; indent_down(); - f_all << endl; - f_all << "type" << endl; + f_all << '\n'; + f_all << "type" << '\n'; if (has_forward) { - f_all << s_forward_decr.str() << endl; + f_all << s_forward_decr.str() << '\n'; } if (has_enum) { - indent(f_all) << endl; - indent(f_all) << "{$SCOPEDENUMS ON}" << endl << endl; + indent(f_all) << '\n'; + indent(f_all) << "{$SCOPEDENUMS ON}" << '\n' << '\n'; f_all << s_enum.str(); - indent(f_all) << "{$SCOPEDENUMS OFF}" << endl << endl; + indent(f_all) << "{$SCOPEDENUMS OFF}" << '\n' << '\n'; } f_all << s_struct.str(); f_all << s_service.str(); f_all << s_const.str(); - f_all << "implementation" << endl << endl; + f_all << "implementation" << '\n' << '\n'; f_all << s_struct_impl.str(); f_all << s_service_impl.str(); f_all << s_const_impl.str(); if (register_types_) { - f_all << endl; - f_all << "// Type factory methods and registration" << endl; + f_all << '\n'; + f_all << "// Type factory methods and registration" << '\n'; f_all << s_type_factory_funcs.str(); - f_all << "procedure RegisterTypeFactories;" << endl; - f_all << "begin" << endl; + f_all << "procedure RegisterTypeFactories;" << '\n'; + f_all << "begin" << '\n'; f_all << s_type_factory_registration.str(); - f_all << "end;" << endl; + f_all << "end;" << '\n'; } - f_all << endl; + f_all << '\n'; string constants_class = make_constants_classname(); - f_all << "initialization" << endl; + f_all << "initialization" << '\n'; if (has_const) { - f_all << "{$IF CompilerVersion < 21.0} // D2010" << endl; - f_all << " " << constants_class.c_str() << "_Initialize;" << endl; - f_all << "{$IFEND}" << endl; + f_all << "{$IF CompilerVersion < 21.0} // D2010" << '\n'; + f_all << " " << constants_class.c_str() << "_Initialize;" << '\n'; + f_all << "{$IFEND}" << '\n'; } if (register_types_) { - f_all << " RegisterTypeFactories;" << endl; + f_all << " RegisterTypeFactories;" << '\n'; } - f_all << endl; + f_all << '\n'; - f_all << "finalization" << endl; + f_all << "finalization" << '\n'; if (has_const) { - f_all << "{$IF CompilerVersion < 21.0} // D2010" << endl; - f_all << " " << constants_class.c_str() << "_Finalize;" << endl; - f_all << "{$IFEND}" << endl; + f_all << "{$IF CompilerVersion < 21.0} // D2010" << '\n'; + f_all << " " << constants_class.c_str() << "_Finalize;" << '\n'; + f_all << "{$IFEND}" << '\n'; } - f_all << endl << endl; + f_all << '\n' << '\n'; - f_all << "end." << endl; + f_all << "end." << '\n'; f_all.close(); if (!typedefs_pending.empty()) { @@ -838,8 +793,8 @@ void t_delphi_generator::close_generator() { void t_delphi_generator::delphi_type_usings(ostream& out) { indent_up(); indent(out) << "Classes, SysUtils, Generics.Collections, Thrift.Collections, Thrift.Protocol," - << endl; - indent(out) << "Thrift.Transport;" << endl << endl; + << '\n'; + indent(out) << "Thrift.Transport;" << '\n' << '\n'; indent_down(); } @@ -848,11 +803,11 @@ void t_delphi_generator::generate_forward_declaration(t_struct* tstruct) { has_forward = true; pdebug("forward declaration of %s\n", type_name(tstruct).c_str()); - string what = tstruct->is_xception() ? "class" : "interface"; - indent_up(); - indent(s_forward_decr) << type_name(tstruct, tstruct->is_xception(), true) << " = " << what << ";" - << endl; + indent(s_forward_decr) << type_name(tstruct, false, true) << " = interface;" << '\n'; + if( tstruct->is_xception()) { + indent(s_forward_decr) << type_name(tstruct, true, true) << " = class;" << '\n'; + } indent_down(); add_defined_type(tstruct); @@ -877,7 +832,7 @@ void t_delphi_generator::generate_typedef(t_typedef* ttypedef) { // if( ! container) // s_struct << "type "; //the "type A = type B" syntax leads to E2574 with generics - s_struct << type_name(ttypedef->get_type()) << ";" << endl << endl; + s_struct << type_name(ttypedef->get_type()) << ";" << '\n' << '\n'; indent_down(); add_defined_type(ttypedef); @@ -958,7 +913,7 @@ void t_delphi_generator::generate_enum(t_enum* tenum) { indent_up(); generate_delphi_doc(s_enum, tenum); indent(s_enum) << type_name(tenum, true, true) << " = " - << "(" << endl; + << "(" << '\n'; indent_up(); vector constants = tenum->get_constants(); if (constants.empty()) { @@ -969,16 +924,19 @@ void t_delphi_generator::generate_enum(t_enum* tenum) { int value = (*c_iter)->get_value(); if (c_iter != constants.begin()) { s_enum << ","; - s_enum << endl; + s_enum << '\n'; } generate_delphi_doc(s_enum, *c_iter); indent(s_enum) << normalize_name((*c_iter)->get_name()) << " = " << value; + s_enum << render_deprecation_attribute((*c_iter)->annotations_, " {", "}"); } } - s_enum << endl; + s_enum << '\n'; indent_down(); - indent(s_enum) << ");" << endl << endl; + indent(s_enum) << ")" << render_deprecation_attribute(tenum->annotations_, " ", "") << ";" << '\n' << '\n'; indent_down(); + + add_defined_type(tenum); } std::string t_delphi_generator::make_pascal_string_literal(std::string value) { @@ -991,7 +949,7 @@ std::string t_delphi_generator::make_pascal_string_literal(std::string value) { result << "'"; for (signed char const c: value) { if( (c >= 0) && (c < 32)) { // convert ctrl chars, but leave UTF-8 alone - result << "#" << (int)c; + result << "#" << (int)c; } else if (c == '\'') { result << "''"; // duplicate any single quotes we find } else { @@ -999,7 +957,7 @@ std::string t_delphi_generator::make_pascal_string_literal(std::string value) { } } result << "'"; - + return result.str(); } @@ -1047,8 +1005,8 @@ void t_delphi_generator::generate_consts(std::vector consts) { string constants_class = make_constants_classname(); indent_up(); - indent(s_const) << constants_class.c_str() << " = class" << endl; - indent(s_const) << "private" << endl; + indent(s_const) << constants_class.c_str() << " = class" << '\n'; + indent(s_const) << "private" << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -1060,7 +1018,7 @@ void t_delphi_generator::generate_consts(std::vector consts) { } } indent_down(); - indent(s_const) << "public" << endl; + indent(s_const) << "public" << '\n'; indent_up(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { generate_delphi_doc(s_const, *c_iter); @@ -1069,12 +1027,12 @@ void t_delphi_generator::generate_consts(std::vector consts) { (*c_iter)->get_type(), (*c_iter)->get_value()); } - indent(s_const) << "{$IF CompilerVersion >= 21.0}" << endl; - indent(s_const) << "class constructor Create;" << endl; - indent(s_const) << "class destructor Destroy;" << endl; - indent(s_const) << "{$IFEND}" << endl; + indent(s_const) << "{$IF CompilerVersion >= 21.0}" << '\n'; + indent(s_const) << "class constructor Create;" << '\n'; + indent(s_const) << "class destructor Destroy;" << '\n'; + indent(s_const) << "{$IFEND}" << '\n'; indent_down(); - indent(s_const) << "end;" << endl << endl; + indent(s_const) << "end;" << '\n' << '\n'; indent_down(); std::ostringstream vars, code; @@ -1085,26 +1043,27 @@ void t_delphi_generator::generate_consts(std::vector consts) { code, prop_name((*c_iter)->get_name(), false, "F"), (*c_iter)->get_type(), - (*c_iter)->get_value()); + (*c_iter)->get_value(), + true); } indent_down_impl(); - indent_impl(s_const_impl) << "{$IF CompilerVersion >= 21.0}" << endl; + indent_impl(s_const_impl) << "{$IF CompilerVersion >= 21.0}" << '\n'; indent_impl(s_const_impl) << "class constructor " << constants_class.c_str() << ".Create;" - << endl; + << '\n'; if (!vars.str().empty()) { - indent_impl(s_const_impl) << "var" << endl; + indent_impl(s_const_impl) << "var" << '\n'; s_const_impl << vars.str(); } - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "begin" << '\n'; if (!code.str().empty()) { s_const_impl << code.str(); } - indent_impl(s_const_impl) << "end;" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n' << '\n'; indent_impl(s_const_impl) << "class destructor " << constants_class.c_str() << ".Destroy;" - << endl; - indent_impl(s_const_impl) << "begin" << endl; + << '\n'; + indent_impl(s_const_impl) << "begin" << '\n'; indent_up_impl(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { if (const_needs_var((*c_iter)->get_type())) { @@ -1114,10 +1073,10 @@ void t_delphi_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } } - indent_impl(s_const_impl) << "inherited;" << endl; + indent_impl(s_const_impl) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(s_const_impl) << "end;" << endl; - indent_impl(s_const_impl) << "{$ELSE}" << endl; + indent_impl(s_const_impl) << "end;" << '\n'; + indent_impl(s_const_impl) << "{$ELSE}" << '\n'; vars.str(""); code.str(""); @@ -1129,24 +1088,25 @@ void t_delphi_generator::generate_consts(std::vector consts) { code, constants_class + "." + prop_name((*c_iter)->get_name(), false, "F"), (*c_iter)->get_type(), - (*c_iter)->get_value()); + (*c_iter)->get_value(), + true); } } indent_down_impl(); - indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Initialize;" << endl; + indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Initialize;" << '\n'; if (!vars.str().empty()) { - indent_impl(s_const_impl) << "var" << endl; + indent_impl(s_const_impl) << "var" << '\n'; s_const_impl << vars.str(); } - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "begin" << '\n'; if (!code.str().empty()) { s_const_impl << code.str(); } - indent_impl(s_const_impl) << "end;" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n' << '\n'; - indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Finalize;" << endl; - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Finalize;" << '\n'; + indent_impl(s_const_impl) << "begin" << '\n'; indent_up_impl(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { finalize_field(s_const_impl, @@ -1156,8 +1116,8 @@ void t_delphi_generator::generate_consts(std::vector consts) { constants_class); } indent_down_impl(); - indent_impl(s_const_impl) << "end;" << endl; - indent_impl(s_const_impl) << "{$IFEND}" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n'; + indent_impl(s_const_impl) << "{$IFEND}" << '\n' << '\n'; } void t_delphi_generator::print_const_def_value(std::ostream& vars, @@ -1190,10 +1150,10 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - string val = render_const_value(vars, out, name, field_type, v_iter->second); + string val = render_const_value(vars, out, field_type, v_iter->second, false); indent_impl(out) << cls_prefix << normalize_name(name) << "." << prop_name(v_iter->first->get_string(), type->is_xception()) - << " := " << val << ";" << endl; + << " := " << val << ";" << '\n'; } } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); @@ -1201,10 +1161,10 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string key = render_const_value(vars, out, name, ktype, v_iter->first); - string val = render_const_value(vars, out, name, vtype, v_iter->second); + string key = render_const_value(vars, out, ktype, v_iter->first, false); + string val = render_const_value(vars, out, vtype, v_iter->second, false); indent_impl(out) << cls_prefix << normalize_name(name) << "[" << key << "]" - << " := " << val << ";" << endl; + << " := " << val << ";" << '\n'; } } else if (type->is_list() || type->is_set()) { t_type* etype; @@ -1217,8 +1177,8 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string val = render_const_value(vars, out, name, etype, *v_iter); - indent_impl(out) << cls_prefix << normalize_name(name) << ".Add(" << val << ");" << endl; + string val = render_const_value(vars, out, etype, *v_iter, false); + indent_impl(out) << cls_prefix << normalize_name(name) << ".Add(" << val << ");" << '\n'; } } } @@ -1228,15 +1188,25 @@ void t_delphi_generator::print_private_field(std::ostream& out, t_type* type, t_const_value* value) { (void)value; - indent(out) << "class var F" << name << ": " << type_name(type) << ";" << endl; + indent(out) << "class var F" << name << ": " << type_name(type) << ";" << '\n'; } bool t_delphi_generator::const_needs_var(t_type* type) { - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); + t_type* truetype = type->get_true_type(); + + if(!truetype->is_base_type()) { + return true; + } + + t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); + switch (tbase) { + case t_base_type::TYPE_UUID: + return true; + case t_base_type::TYPE_STRING: + return truetype->is_binary(); + default: + return false; } - return (!truetype->is_base_type()); } void t_delphi_generator::print_const_prop(std::ostream& out, @@ -1246,11 +1216,11 @@ void t_delphi_generator::print_const_prop(std::ostream& out, (void)value; if (const_needs_var(type)) { indent(out) << "class property " << name << ": " << type_name(type) << " read F" << name << ";" - << endl; + << '\n'; } else { std::ostringstream vars; // dummy - string v2 = render_const_value(vars, out, name, type, value); - indent(out) << "const " << name << " = " << v2 << ";" << endl; + string v2 = render_const_value(vars, out, type, value, true); + indent(out) << "const " << name << " = " << v2 << ";" << '\n'; } } @@ -1258,23 +1228,21 @@ void t_delphi_generator::print_const_value(std::ostream& vars, std::ostream& out, string name, t_type* type, - t_const_value* value) { - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); - } + t_const_value* value, + bool is_const_class) { + t_type* truetype = type->get_true_type(); if (truetype->is_base_type()) { - // already done - // string v2 = render_const_value( vars, out, name, type, value); - // indent_impl(out) << name << " := " << v2 << ";" << endl; + if(const_needs_var(type) || (!is_const_class)) { + string the_value = render_const_value( vars, out, type, value, false); + indent_impl(out) << name << " := " << the_value << ";" << '\n'; + } } else if (truetype->is_enum()) { indent_impl(out) << name << " := " << type_name(type) << "." << value->get_identifier_name() - << ";" << endl; + << ";" << '\n'; } else { - string typname; - typname = type_name(truetype, true, false, type->is_xception(), type->is_xception()); - indent_impl(out) << name << " := " << typname << ".Create;" << endl; + string typname = type_name(truetype, true, false/*, type->is_xception(), type->is_xception()*/); + indent_impl(out) << name << " := " << typname << ".Create;" << '\n'; print_const_def_value(vars, out, name, truetype, value); } } @@ -1283,8 +1251,9 @@ void t_delphi_generator::initialize_field(std::ostream& vars, std::ostream& out, string name, t_type* type, - t_const_value* value) { - print_const_value(vars, out, name, type, value); + t_const_value* value, + bool is_const_class) { + print_const_value(vars, out, name, type, value, is_const_class); } void t_delphi_generator::finalize_field(std::ostream& out, @@ -1301,15 +1270,10 @@ void t_delphi_generator::finalize_field(std::ostream& out, string t_delphi_generator::render_const_value(ostream& vars, ostream& out, - string name, t_type* type, - t_const_value* value) { - (void)name; - - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); - } + t_const_value* value, + bool guidAsLiteral) { + t_type* truetype = type->get_true_type(); std::ostringstream render; @@ -1317,10 +1281,18 @@ string t_delphi_generator::render_const_value(ostream& vars, t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); switch (tbase) { case t_base_type::TYPE_STRING: - render << "'" << get_escaped_string(value) << "'"; + if (truetype->is_binary()) { + render << "TEncoding.UTF8.GetBytes('" << get_escaped_string(value) << "')"; + } else { + render << "'" << get_escaped_string(value) << "'"; + } break; case t_base_type::TYPE_UUID: - render << "['{" << value->get_uuid() << "}']"; + if(guidAsLiteral) { + render << "['{" << value->get_uuid() << "}']"; + } else { + render << "StringToGUID('{" << value->get_uuid() << "}')"; + } break; case t_base_type::TYPE_BOOL: render << ((value->get_integer() > 0) ? "True" : "False"); @@ -1351,8 +1323,8 @@ string t_delphi_generator::render_const_value(ostream& vars, render << type_name(type, false) << "." << value->get_identifier_name(); } else { string t = tmp("tmp"); - vars << " " << t << " : " << type_name(type) << ";" << endl; - print_const_value(vars, out, t, type, value); + vars << " " << t << " : " << type_name(type) << ";" << '\n'; + print_const_value(vars, out, t, type, value, true); render << t; } @@ -1360,54 +1332,54 @@ string t_delphi_generator::render_const_value(ostream& vars, } void t_delphi_generator::generate_struct(t_struct* tstruct) { - generate_delphi_struct(tstruct, false); + generate_delphi_struct(tstruct); } void t_delphi_generator::generate_xception(t_struct* txception) { - generate_delphi_struct(txception, true); + generate_delphi_exception(txception); } -void t_delphi_generator::generate_delphi_struct(t_struct* tstruct, bool is_exception) { +void t_delphi_generator::generate_delphi_struct(t_struct* tstruct) { indent_up(); - generate_delphi_struct_definition(s_struct, tstruct, is_exception); + generate_delphi_struct_definition(s_struct, tstruct); indent_down(); add_defined_type(tstruct); - generate_delphi_struct_impl(s_struct_impl, "", tstruct, is_exception); + generate_delphi_struct_impl(s_struct_impl, "", tstruct, false, false/*?*/); if (register_types_) { - generate_delphi_struct_type_factory(s_type_factory_funcs, "", tstruct, is_exception); - generate_delphi_struct_type_factory_registration(s_type_factory_registration, - "", - tstruct, - is_exception); + generate_delphi_struct_type_factory(s_type_factory_funcs, "", tstruct); + generate_delphi_struct_type_factory_registration(s_type_factory_registration, "", tstruct); } } -void t_delphi_generator::generate_delphi_struct_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { - - if (is_exception && (!is_x_factory)) { - generate_delphi_struct_impl(out, cls_prefix, tstruct, is_exception, is_result, true); - } +void t_delphi_generator::generate_delphi_exception(t_struct* tstruct) { + // generate exception data class first + generate_delphi_struct(tstruct); - string cls_nm; + indent_up(); + generate_delphi_exception_definition(s_struct, tstruct); + indent_down(); - string exception_factory_name; + add_defined_type(tstruct); - if (is_exception) { - exception_factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; + generate_delphi_exception_impl(s_struct_impl, "", tstruct); + /* + if (register_types_) { + generate_delphi_exception_type_factory(s_type_factory_funcs, "", tstruct); + generate_delphi_exception_type_factory_registration(s_type_factory_registration, "", tstruct); } + */ +} - if (is_exception) { - cls_nm = type_name(tstruct, true, (!is_x_factory), is_x_factory, true); - } else { - cls_nm = type_name(tstruct, true, false); - } +void t_delphi_generator::generate_delphi_struct_impl(ostream& out, + string cls_prefix, + t_struct* tstruct, + bool is_result, + bool is_const_class) { + (void)is_result; + + string cls_nm = type_name(tstruct, true, false); std::ostringstream vars, code; @@ -1416,123 +1388,58 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out, indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } + t_type* truetype = (*m_iter)->get_type()->get_true_type(); if ((*m_iter)->get_value() != nullptr) { initialize_field(vars, code, - prop_name((*m_iter)->get_name(), is_exception, ""), - t, - (*m_iter)->get_value()); + prop_name((*m_iter)->get_name(), false, "F"), + truetype, + (*m_iter)->get_value(), + is_const_class); if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent_impl(code) << prop_name((*m_iter), is_exception, "F__isset_") << " := True;" - << endl; + indent_impl(code) << prop_name((*m_iter), false, "F__isset_") << " := True;" << '\n'; } } } indent_down_impl(); - indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." - << "Create;" << endl; + indent_impl(out) << "constructor " << cls_prefix << cls_nm << ".Create;" << '\n'; if (!vars.str().empty()) { - out << "var" << endl; + out << "var" << '\n'; out << vars.str(); } - indent_impl(out) << "begin" << endl; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - if (is_exception && (!is_x_factory)) { - indent_impl(out) << "inherited Create('');" << endl; - } else { - indent_impl(out) << "inherited;" << endl; - } + indent_impl(out) << "inherited;" << '\n'; if (!code.str().empty()) { out << code.str(); } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; - if ((members.size() > 0) && is_exception && (!is_x_factory)) { - indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." - << "Create(" << constructor_argument_list(tstruct, indent_impl()) << ");" - << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "Create;" << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - string propname = prop_name((*m_iter)->get_name(), is_exception); - string param_name = constructor_param_name((*m_iter)->get_name()); - indent_impl(out) << propname << " := " << param_name << ";" << endl; - } - indent_impl(out) << "UpdateMessageProperty;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - } - - indent_impl(out) << "destructor " << cls_prefix << cls_nm << "." - << "Destroy;" << endl; - indent_impl(out) << "begin" << endl; + indent_impl(out) << "destructor " << cls_prefix << cls_nm << ".Destroy;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } - finalize_field(out, prop_name(*m_iter, is_exception), t, (*m_iter)->get_value()); + t_type* t = (*m_iter)->get_type()->get_true_type(); + finalize_field(out, prop_name(*m_iter, false), t, (*m_iter)->get_value()); } - indent_impl(out) << "inherited;" << endl; + indent_impl(out) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - - if (is_exception && (!is_x_factory)) { - indent_impl(out) << "function " << cls_prefix << cls_nm << "." << exception_factory_name - << ": I" << exception_factory_name << ";" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "if F" << exception_factory_name << " = nil" << endl; - indent_impl(out) << "then F" << exception_factory_name << " := T" << exception_factory_name << "Impl.Create;" << endl << endl; - indent_impl(out) << "result := F" << exception_factory_name << ";" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << ".QueryInterface(const IID: TGUID; out Obj): HRESULT;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "if GetInterface(IID, Obj)" << endl; - indent_impl(out) << "then result := S_OK" << endl; - indent_impl(out) << "else result := E_NOINTERFACE;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << "._AddRef: Integer;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "result := -1; // not refcounted" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << "._Release: Integer;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "result := -1; // not refcounted" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - } + indent_impl(out) << "end;" << '\n' << '\n'; if (tstruct->is_union()) { - indent_impl(out) << "procedure " << cls_prefix << cls_nm << "." - << "ClearUnionValues;" << endl; - indent_impl(out) << "begin" << endl; + indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".ClearUnionValues;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } + t_type* t = (*m_iter)->get_type()->get_true_type(); generate_delphi_clear_union_value(out, cls_prefix, @@ -1540,47 +1447,136 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out, t, *m_iter, "F", - is_exception, - tstruct->is_union(), - is_x_factory, - exception_factory_name); + false, + tstruct->is_union()); } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } - generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", is_exception); + t_type* t = (*m_iter)->get_type()->get_true_type(); + generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", false); generate_delphi_property_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", - is_exception, - tstruct->is_union(), - is_x_factory, - exception_factory_name); + false, + tstruct->is_union()); if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", is_exception); + generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", false); } } - generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - if (is_result) { - generate_delphi_struct_result_writer_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - } else { - generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); + generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, false); + generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, false); + generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, false); +} + +void t_delphi_generator::generate_delphi_exception_impl(ostream& out, + string cls_prefix, + t_struct* tstruct) { + + string cls_nm = type_name(tstruct, true, true/*, false, true*/); + + const vector& members = tstruct->get_members(); + vector::const_iterator m_iter; + + indent_impl(out) << "constructor " << cls_prefix << cls_nm << ".Create;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "inherited Create('');" << '\n'; + indent_impl(out) << "FData := " << type_name(tstruct, true, false) << ".Create;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + if (members.size() > 0) { + indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." + << "Create(" << constructor_argument_list(tstruct, indent_impl()) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "Create;" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + string propname = prop_name((*m_iter)->get_name(), true); + string param_name = constructor_param_name((*m_iter)->get_name()); + indent_impl(out) << propname << " := " << param_name << ";" << '\n'; + } + indent_impl(out) << "UpdateMessageProperty;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + } + + indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." + << "Create(const aData: " << type_name(tstruct, false, false) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "inherited Create('');" << '\n'; + indent_impl(out) << "if aData <> nil" << '\n'; + indent_impl(out) << "then FData := aData" << '\n'; + indent_impl(out) << "else ASSERT(FALSE,'Invalid argument');" << '\n'; + indent_impl(out) << "UpdateMessageProperty;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + indent_impl(out) << "destructor " << cls_prefix << cls_nm << "." + << "Destroy;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = (*m_iter)->get_type()->get_true_type(); + finalize_field(out, prop_name(*m_iter, true), t, (*m_iter)->get_value()); } - generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - if (is_exception && is_x_factory) { - generate_delphi_create_exception_impl(out, cls_prefix, tstruct, is_exception); + indent_impl(out) << "inherited;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + // non-refcounted IUnknown impl + indent_impl(out) << "function " << cls_prefix << cls_nm << ".QueryInterface(const IID: TGUID; out Obj): HRESULT;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "if GetInterface(IID, Obj)" << '\n'; + indent_impl(out) << "then result := S_OK" << '\n'; + indent_impl(out) << "else result := E_NOINTERFACE;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + indent_impl(out) << "function " << cls_prefix << cls_nm << "._AddRef: Integer;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "result := -1; // not refcounted" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + indent_impl(out) << "function " << cls_prefix << cls_nm << "._Release: Integer;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "result := -1; // not refcounted" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = (*m_iter)->get_type()->get_true_type(); + generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "", true); + generate_delphi_property_writer_impl(out, + cls_prefix, + cls_nm, + t, + *m_iter, + "", + true, + tstruct->is_union()); + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "", true); + } } + + generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, true); + generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, true); + generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, true); } void t_delphi_generator::print_delphi_struct_type_factory_func(ostream& out, t_struct* tstruct) { @@ -1592,17 +1588,8 @@ void t_delphi_generator::print_delphi_struct_type_factory_func(ostream& out, t_s void t_delphi_generator::generate_delphi_struct_type_factory(ostream& out, string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { + t_struct* tstruct) { (void)cls_prefix; - if (is_exception) - return; - if (is_result) - return; - if (is_x_factory) - return; string struct_intf_name = type_name(tstruct); string cls_nm = type_name(tstruct, true, false); @@ -1611,42 +1598,29 @@ void t_delphi_generator::generate_delphi_struct_type_factory(ostream& out, print_delphi_struct_type_factory_func(out, tstruct); out << ": "; out << struct_intf_name; - out << ";" << endl; - out << "begin" << endl; + out << ";" << '\n'; + out << "begin" << '\n'; indent_up(); - indent(out) << "Result := " << cls_nm << ".Create;" << endl; + indent(out) << "Result := " << cls_nm << ".Create;" << '\n'; indent_down(); - out << "end;" << endl << endl; + out << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_struct_type_factory_registration(ostream& out, string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { + t_struct* tstruct) { (void)cls_prefix; - if (is_exception) - return; - if (is_result) - return; - if (is_x_factory) - return; string struct_intf_name = type_name(tstruct); indent(out) << " TypeRegistry.RegisterTypeFactory<" << struct_intf_name << ">("; print_delphi_struct_type_factory_func(out, tstruct); out << ");"; - out << endl; + out << '\n'; } -void t_delphi_generator::generate_delphi_struct_definition(ostream& out, - t_struct* tstruct, - bool is_exception, - bool in_class, - bool is_result, - bool is_x_factory) { +void t_delphi_generator::generate_delphi_struct_definition(ostream& out, + t_struct* tstruct) { bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); string struct_intf_name; string struct_name; @@ -1654,232 +1628,252 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - string exception_factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; - - if (is_exception) { - struct_intf_name = type_name(tstruct, false, false, true); - } else { - struct_intf_name = type_name(tstruct); - } + struct_intf_name = type_name(tstruct, false, false); + struct_name = type_name(tstruct, true); - if (is_exception) { - struct_name = type_name(tstruct, true, (!is_x_factory), is_x_factory); + generate_delphi_doc(out, tstruct); + if(rtti_) { + indent(out) << "{$TYPEINFO ON}" << '\n'; + indent(out) << "{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}" << '\n'; + indent(out) << struct_intf_name << " = interface(IBaseWithTypeInfo)" << '\n'; } else { - struct_name = type_name(tstruct, true); + indent(out) << struct_intf_name << " = interface(IBase)" << '\n'; } + indent_up(); - if ((!is_exception) || is_x_factory) { - - generate_delphi_doc(out, tstruct); - if(rtti_) { - indent(out) << "{$TYPEINFO ON}" << endl; - indent(out) << "{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}" << endl; - indent(out) << struct_intf_name << " = interface(IBaseWithTypeInfo)" << endl; - } else { - indent(out) << struct_intf_name << " = interface(IBase)" << endl; - } - indent_up(); + generate_guid(out); - generate_guid(out); + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_delphi_property_reader_definition(out, *m_iter, false); + generate_delphi_property_writer_definition(out, *m_iter, false); + } + if (members.size() > 0) { + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_delphi_property_reader_definition(out, *m_iter, is_exception); - generate_delphi_property_writer_definition(out, *m_iter, is_exception); - } - - if (is_x_factory) { - out << endl; - indent(out) << "// Create Exception Object" << endl; - indent(out) << "function CreateException: " << type_name(tstruct, true, true) << ";" << endl; + generate_property(out, *m_iter, true, false); } - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_property(out, *m_iter, true, is_exception); - } - } - - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - generate_delphi_isset_reader_writer_definition(out, *m_iter, is_exception); - } + out << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + generate_delphi_isset_reader_writer_definition(out, *m_iter, false); } } - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); - indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" - << endl; - } + out << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" + << '\n'; } } + } - indent_down(); - indent(out) << "end;" << endl; - if(rtti_) { - indent(out) << "{$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}" << endl; - } - indent(out) << endl; + indent_down(); + indent(out) << "end;" + << render_deprecation_attribute(tstruct->annotations_, " {", "}") + << '\n'; + if(rtti_) { + indent(out) << "{$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}" << '\n'; } + indent(out) << '\n'; generate_delphi_doc(out, tstruct); indent(out) << struct_name << " = "; if (is_final) { out << "sealed "; } - out << "class("; - if (is_exception && (!is_x_factory)) { - out << "TException, IInterface, IBase, ISupportsToString"; - } else { - out << "TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name; - } - out << ")" << endl; + out << "class(TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name << ")" << '\n'; - if (is_exception && (!is_x_factory)) { - indent(out) << "public" << endl; - indent_up(); - indent(out) << "type" << endl; - indent_up(); - generate_delphi_struct_definition(out, tstruct, is_exception, in_class, is_result, true); - indent_down(); - indent_down(); - } - - indent(out) << "private" << endl; + indent(out) << "private" << '\n'; indent_up(); - if (is_exception && (!is_x_factory)) { - indent(out) << "F" << exception_factory_name << " :" << struct_intf_name << ";" << endl << endl; - } - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - indent(out) << declare_field(*m_iter, false, "F", is_exception) << endl; + indent(out) << declare_field(*m_iter, "F", false) << '\n'; } if (members.size() > 0) { - indent(out) << endl; + indent(out) << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "F__isset_"); - indent(out) << isset_name << ": System.Boolean;" << endl; + isset_name = prop_name(*m_iter, false, "F__isset_"); + indent(out) << isset_name << ": System.Boolean;" << '\n'; } } } - indent(out) << endl; + indent(out) << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_delphi_property_reader_definition(out, *m_iter, is_exception); - generate_delphi_property_writer_definition(out, *m_iter, is_exception); + generate_delphi_property_reader_definition(out, *m_iter, false); + generate_delphi_property_writer_definition(out, *m_iter, false); } if (tstruct->is_union()) { - out << endl; - indent(out) << "// Clear values(for union's property setter)" << endl; - indent(out) << "procedure ClearUnionValues;" << endl; + out << '\n'; + indent(out) << "// Clear values(for union's property setter)" << '\n'; + indent(out) << "procedure ClearUnionValues;" << '\n'; } if (members.size() > 0) { - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); - indent(out) << "function Get" << isset_name << ": System.Boolean;" << endl; - indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << endl; + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "function Get" << isset_name << ": System.Boolean;" << '\n'; + indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << '\n'; } } } - if (is_exception && (!is_x_factory)) { - out << endl; - indent_down(); - indent(out) << "strict protected" << endl; - indent_up(); - indent(out) << "function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;" << endl; - indent(out) << "function _AddRef: Integer; stdcall;" << endl; - indent(out) << "function _Release: Integer; stdcall;" << endl; - out << endl; - } - indent_down(); - indent(out) << "public" << endl; + indent(out) << "public" << '\n'; indent_up(); + indent(out) << "constructor Create;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + indent(out) << "destructor Destroy; override;" << '\n'; - if ((members.size() > 0) && is_exception && (!is_x_factory)) { - indent(out) << "constructor Create; overload;" << endl; - indent(out) << "constructor Create(" << constructor_argument_list(tstruct, indent()) - << "); overload;" << endl; - } else { - indent(out) << "constructor Create;" << endl; + out << '\n'; + indent(out) << "function ToString: string; override;" << '\n'; + + out << '\n'; + indent(out) << "// IBase" << '\n'; + indent(out) << "procedure Read( const iprot: IProtocol);" << '\n'; + indent(out) << "procedure Write( const oprot: IProtocol);" << '\n'; + + if (members.size() > 0) { + out << '\n'; + indent(out) << "// Properties" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_property(out, *m_iter, true, false); + } + + out << '\n'; + indent(out) << "// isset" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" + << '\n'; + } + } } - indent(out) << "destructor Destroy; override;" << endl; + indent_down(); + indent(out) << "end;" << '\n' << '\n'; +} + +void t_delphi_generator::generate_delphi_exception_definition(ostream& out, + t_struct* tstruct) { + bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + string struct_intf_name; + string struct_name; + string isset_name; + const vector& members = tstruct->get_members(); + vector::const_iterator m_iter; - out << endl; - indent(out) << "function ToString: string; override;" << endl; + struct_intf_name = type_name(tstruct, false, false); + struct_name = type_name(tstruct, true, true); - if (is_exception && (!is_x_factory)) { - out << endl; - indent(out) << "// Exception Factory" << endl; - indent(out) << "function " << exception_factory_name << ": " << struct_intf_name << ";" << endl; + generate_delphi_doc(out, tstruct); + indent(out) << struct_name << " = "; + if (is_final) { + out << "sealed "; } + out << "class(TException, IInterface, IBase, ISupportsToString)" << '\n'; - out << endl; - indent(out) << "// IBase" << endl; - indent(out) << "procedure Read( const iprot: IProtocol);" << endl; - indent(out) << "procedure Write( const oprot: IProtocol);" << endl; + indent(out) << "private" << '\n'; + indent_up(); + indent(out) << "FData : " << struct_intf_name << ';' << '\n'; + indent(out) << '\n'; - if (is_exception && is_x_factory) { - out << endl; - indent(out) << "// Create Exception Object" << endl; - indent(out) << "function CreateException: " << type_name(tstruct, true, true) << ";" << endl; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_delphi_property_reader_definition(out, *m_iter, true); + generate_delphi_property_writer_definition(out, *m_iter, true); } if (members.size() > 0) { - out << endl; - indent(out) << "// Properties" << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_property(out, *m_iter, true, is_exception); + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, true, "__isset_"); + indent(out) << "function Get" << isset_name << ": System.Boolean;" << '\n'; + indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << '\n'; + } } } + out << '\n'; + indent_down(); + indent(out) << "strict protected" << '\n'; + indent_up(); + indent(out) << "// non-refcounted instance" << '\n'; + indent(out) << "function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;" << '\n'; + indent(out) << "function _AddRef: Integer; stdcall;" << '\n'; + indent(out) << "function _Release: Integer; stdcall;" << '\n'; + out << '\n'; + + indent_down(); + indent(out) << "public" << '\n'; + indent_up(); + + indent(out) << "constructor Create; overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + if (members.size() > 0) { + indent(out) << "constructor Create(" << constructor_argument_list(tstruct, indent()) + << "); overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + } + indent(out) << "constructor Create( const aData: " << struct_intf_name + << "); overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + + indent(out) << "destructor Destroy; override;" << '\n'; + + out << '\n'; + indent(out) << "property ExceptionData : " << struct_intf_name << " read FData;" << '\n'; + indent(out) << "function ToString: string; override;" << '\n'; + + out << '\n'; + indent(out) << "// IBase" << '\n'; + indent(out) << "procedure Read( const iprot: IProtocol);" << '\n'; + indent(out) << "procedure Write( const oprot: IProtocol);" << '\n'; + if (members.size() > 0) { - out << endl; - indent(out) << "// isset" << endl; + out << '\n'; + indent(out) << "// Properties" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_property(out, *m_iter, true, true); + } + + out << '\n'; + indent(out) << "// isset" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); + isset_name = prop_name(*m_iter, true, "__isset_"); indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" - << endl; + << '\n'; } } } indent_down(); - indent(out) << "end;" << endl << endl; + indent(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_service(t_service* tservice) { indent_up(); generate_delphi_doc(s_service, tservice); - indent(s_service) << normalize_clsnm(service_name_, "T") << " = class" << endl; - indent(s_service) << "public" << endl; + indent(s_service) << normalize_clsnm(service_name_, "T") << " = class" << '\n'; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "type" << endl; + indent(s_service) << "type" << '\n'; generate_service_interface(tservice); generate_service_client(tservice); generate_service_server(tservice); generate_service_helpers(tservice); indent_down(); indent_down(); - indent(s_service) << "end;" << endl; - indent(s_service) << endl; + indent(s_service) << "end;" << '\n'; + indent(s_service) << '\n'; indent_down(); } @@ -1903,9 +1897,9 @@ void t_delphi_generator::generate_service_interface(t_service* tservice, bool fo extends = type_name(tservice->get_extends(), true, true); extends_iface = extends + "." + iface_name; generate_delphi_doc(s_service, tservice); - indent(s_service) << iface_name << " = interface(" << extends_iface << ")" << endl; + indent(s_service) << iface_name << " = interface(" << extends_iface << ")" << '\n'; } else { - indent(s_service) << iface_name << " = interface" << endl; + indent(s_service) << iface_name << " = interface" << '\n'; } indent_up(); @@ -1914,10 +1908,12 @@ void t_delphi_generator::generate_service_interface(t_service* tservice, bool fo vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, for_async) << endl; + indent(s_service) << function_signature(*f_iter, for_async) << '\n'; } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" + << render_deprecation_attribute( tservice->annotations_, " {", "}") + << '\n' << '\n'; indent_down(); } @@ -1931,7 +1927,7 @@ void t_delphi_generator::generate_guid(std::ostream& out) { std::wstring guid_wstr(guid_chars); std::wstring_convert> convert; std::string guid_str = convert.to_bytes(guid_wstr); - indent(out) << "['" << guid_str << "']" << endl; + indent(out) << "['" << guid_str << "']" << '\n'; } } #else @@ -1945,11 +1941,11 @@ void t_delphi_generator::generate_service_helpers(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); - generate_delphi_struct_definition(s_service, ts, false, true); + generate_delphi_struct_definition(s_service, ts); generate_delphi_struct_impl(s_service_impl, normalize_clsnm(service_name_, "T") + ".", ts, - false); + false, false); generate_function_helpers(*f_iter); } } @@ -1965,78 +1961,78 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { extends = type_name(tservice->get_extends(), true, true); extends_client = extends + ".TClient"; } - indent(s_service) << "TClient = class( " << extends_client << ", " << implements << ")" << endl; + indent(s_service) << "TClient = class( " << extends_client << ", " << implements << ")" << '\n'; - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "constructor Create( prot: IProtocol); overload;" << endl; + indent(s_service) << "constructor Create( prot: IProtocol); overload;" << '\n'; indent_impl(s_service_impl) << "constructor " << normalize_clsnm(service_name_, "T") - << ".TClient.Create( prot: IProtocol);" << endl; - indent_impl(s_service_impl) << "begin" << endl; + << ".TClient.Create( prot: IProtocol);" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Create( prot, prot );" << endl; + indent_impl(s_service_impl) << "Create( prot, prot );" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; indent(s_service) - << "constructor Create( const iprot: IProtocol; const oprot: IProtocol); overload;" << endl; + << "constructor Create( const iprot: IProtocol; const oprot: IProtocol); overload;" << '\n'; indent_impl(s_service_impl) << "constructor " << normalize_clsnm(service_name_, "T") << ".TClient.Create( const iprot: IProtocol; const oprot: IProtocol);" - << endl; - indent_impl(s_service_impl) << "begin" << endl; + << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "inherited Create;" << endl; - indent_impl(s_service_impl) << "iprot_ := iprot;" << endl; - indent_impl(s_service_impl) << "oprot_ := oprot;" << endl; + indent_impl(s_service_impl) << "inherited Create;" << '\n'; + indent_impl(s_service_impl) << "iprot_ := iprot;" << '\n'; + indent_impl(s_service_impl) << "oprot_ := oprot;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; indent_down(); if (extends.empty()) { - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "iprot_: IProtocol;" << endl; - indent(s_service) << "oprot_: IProtocol;" << endl; - indent(s_service) << "seqid_: System.Integer;" << endl; + indent(s_service) << "iprot_: IProtocol;" << '\n'; + indent(s_service) << "oprot_: IProtocol;" << '\n'; + indent(s_service) << "seqid_: System.Integer;" << '\n'; indent_down(); - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "property InputProtocol: IProtocol read iprot_;" << endl; - indent(s_service) << "property OutputProtocol: IProtocol read oprot_;" << endl; + indent(s_service) << "property InputProtocol: IProtocol read iprot_;" << '\n'; + indent(s_service) << "property OutputProtocol: IProtocol read oprot_;" << '\n'; indent_down(); } vector functions = tservice->get_functions(); vector::const_iterator f_iter; - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "// Iface" << endl; + indent(s_service) << "// Iface" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string funname = (*f_iter)->get_name(); generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, false) << endl; + indent(s_service) << function_signature(*f_iter, false) << '\n'; } if( async_) { - indent(s_service) << endl; - indent(s_service) << "// IAsync" << endl; + indent(s_service) << '\n'; + indent(s_service) << "// IAsync" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string funname = (*f_iter)->get_name(); generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, true) << endl; + indent(s_service) << function_signature(*f_iter, true) << '\n'; } } indent_down(); - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); string full_cls = normalize_clsnm(service_name_, "T") + ".TClient"; @@ -2054,20 +2050,20 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { bool for_async = (mode != 0); mode--; - indent_impl(s_service_impl) << function_signature(*f_iter, for_async, full_cls) << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << function_signature(*f_iter, for_async, full_cls) << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); t_type* ttype = (*f_iter)->get_returntype(); if( for_async) { if (is_void(ttype)) { // Delphi forces us to specify a type with IFuture, so we use Integer=0 for void methods - indent_impl(s_service_impl) << "result := TTask.Future(function: System.Integer" << endl; + indent_impl(s_service_impl) << "result := TTask.Future(function: System.Integer" << '\n'; } else { - string rettype = type_name(ttype, false, true, false, true); - indent_impl(s_service_impl) << "result := TTask.Future<" << rettype << ">(function: " << rettype << endl; + string rettype = type_name(ttype, false, true/*, false, true*/); + indent_impl(s_service_impl) << "result := TTask.Future<" << rettype << ">(function: " << rettype << '\n'; } - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); } @@ -2082,26 +2078,26 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { } s_service_impl << normalize_name((*fld_iter)->get_name()); } - s_service_impl << ");" << endl; + s_service_impl << ");" << '\n'; if (!(*f_iter)->is_oneway()) { s_service_impl << indent_impl(); if (!(*f_iter)->get_returntype()->is_void()) { s_service_impl << "Result := "; } - s_service_impl << "recv_" << funname << "();" << endl; + s_service_impl << "recv_" << funname << "();" << '\n'; } if( for_async) { if (is_void(ttype)) { - indent_impl(s_service_impl) << "Result := 0;" << endl; // no IFuture in Delphi + indent_impl(s_service_impl) << "Result := 0;" << '\n'; // no IFuture in Delphi } indent_down_impl(); - indent_impl(s_service_impl) << "end);" << endl; + indent_impl(s_service_impl) << "end);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } t_function send_function(g_type_void, @@ -2115,41 +2111,41 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { string argsvar = tmp("_args"); string msgvar = tmp("_msg"); - indent(s_service) << function_signature(&send_function, false) << endl; - indent_impl(s_service_impl) << function_signature(&send_function, false, full_cls) << endl; - indent_impl(s_service_impl) << "var" << endl; + indent(s_service) << function_signature(&send_function, false) << '\n'; + indent_impl(s_service_impl) << function_signature(&send_function, false, full_cls) << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << argsvar << " : " << args_intfnm << ";" << endl; - indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl; + indent_impl(s_service_impl) << argsvar << " : " << args_intfnm << ";" << '\n'; + indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << endl; + indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << '\n'; indent_impl(s_service_impl) << "Thrift.Protocol.Init( " << msgvar << ", '" << funname << "', " << ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") - << ", seqid_);" << endl; + << ", seqid_);" << '\n'; - indent_impl(s_service_impl) << "oprot_.WriteMessageBegin( " << msgvar << " );" << endl; - indent_impl(s_service_impl) << argsvar << " := " << args_clsnm << "Impl.Create();" << endl; + indent_impl(s_service_impl) << "oprot_.WriteMessageBegin( " << msgvar << " );" << '\n'; + indent_impl(s_service_impl) << argsvar << " := " << args_clsnm << "Impl.Create();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent_impl(s_service_impl) << argsvar << "." << prop_name(*fld_iter) << " := " << normalize_name((*fld_iter)->get_name()) << ";" - << endl; + << '\n'; } - indent_impl(s_service_impl) << argsvar << ".Write(oprot_);" << endl; + indent_impl(s_service_impl) << argsvar << ".Write(oprot_);" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent_impl(s_service_impl) << argsvar << "." << prop_name(*fld_iter) - << " := " << empty_value((*fld_iter)->get_type()) << ";" << endl; + << " := " << empty_value((*fld_iter)->get_type()) << ";" << '\n'; } - indent_impl(s_service_impl) << "oprot_.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot_.Transport.Flush();" << endl; + indent_impl(s_service_impl) << "oprot_.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot_.Transport.Flush();" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; if (!(*f_iter)->is_oneway()) { string org_resultname = (*f_iter)->get_name() + "_result"; @@ -2169,72 +2165,76 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { string appexvar = tmp("_ax"); string retvar = tmp("_ret"); - indent(s_service) << function_signature(&recv_function, false) << endl; - indent_impl(s_service_impl) << function_signature(&recv_function, false, full_cls) << endl; - indent_impl(s_service_impl) << "var" << endl; + indent(s_service) << function_signature(&recv_function, false) << '\n'; + indent_impl(s_service_impl) << function_signature(&recv_function, false, full_cls) << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl; + indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << '\n'; if (xceptions.size() > 0) { - indent_impl(s_service_impl) << exceptvar << " : Exception;" << endl; + indent_impl(s_service_impl) << exceptvar << " : Exception;" << '\n'; } - indent_impl(s_service_impl) << appexvar << " : TApplicationException;" << endl; - indent_impl(s_service_impl) << retvar << " : " << result_intfnm << ";" << endl; + indent_impl(s_service_impl) << appexvar << " : TApplicationException;" << '\n'; + indent_impl(s_service_impl) << retvar << " : " << result_intfnm << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << msgvar << " := iprot_.ReadMessageBegin();" << endl; - indent_impl(s_service_impl) << "if (" << msgvar << ".Type_ = TMessageType.Exception) then begin" << endl; + indent_impl(s_service_impl) << msgvar << " := iprot_.ReadMessageBegin();" << '\n'; + indent_impl(s_service_impl) << "if (" << msgvar << ".Type_ = TMessageType.Exception) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << appexvar << " := TApplicationException.Read(iprot_);" << endl; - indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << endl; - indent_impl(s_service_impl) << "raise " << appexvar << ";" << endl; + indent_impl(s_service_impl) << appexvar << " := TApplicationException.Read(iprot_);" << '\n'; + indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "raise " << appexvar << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; - indent_impl(s_service_impl) << retvar << " := " << result_clsnm << "Impl.Create();" << endl; - indent_impl(s_service_impl) << retvar << ".Read(iprot_);" << endl; - indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << retvar << " := " << result_clsnm << "Impl.Create();" << '\n'; + indent_impl(s_service_impl) << retvar << ".Read(iprot_);" << '\n'; + indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { - indent_impl(s_service_impl) << "if (" << retvar << ".__isset_success) then begin" << endl; + indent_impl(s_service_impl) << "if (" << retvar << ".__isset_success) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := " << retvar << ".Success;" << endl; + indent_impl(s_service_impl) << "Result := " << retvar << ".Success;" << '\n'; t_type* type = (*f_iter)->get_returntype(); if (type->is_struct() || type->is_xception() || type->is_map() || type->is_list() || type->is_set()) { - indent_impl(s_service_impl) << retvar << ".Success := nil;" << endl; + indent_impl(s_service_impl) << retvar << ".Success := nil;" << '\n'; } - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent_impl(s_service_impl) << "if (" << retvar << "." << prop_name(*x_iter, false, "__isset_") - << ") then begin" << endl; + << ") then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << exceptvar << " := " << retvar << "." << prop_name(*x_iter) - << ".CreateException;" << endl; - indent_impl(s_service_impl) << "raise " << exceptvar << ";" << endl; + indent_impl(s_service_impl) << exceptvar + << " := " << type_name((*x_iter)->get_type(),true,true/*,false,true*/) + << ".Create(" << retvar << "." << prop_name(*x_iter) << ");" + << '\n'; + indent_impl(s_service_impl) << "raise " << exceptvar << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } if (!(*f_iter)->get_returntype()->is_void()) { indent_impl(s_service_impl) << "raise TApplicationExceptionMissingResult.Create('" - << (*f_iter)->get_name() << " failed: unknown result');" << endl; + << (*f_iter)->get_name() << " failed: unknown result');" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" + << render_deprecation_attribute( tservice->annotations_, " {", "}") + << '\n' << '\n'; } void t_delphi_generator::generate_service_server(t_service* tservice) { @@ -2249,164 +2249,164 @@ void t_delphi_generator::generate_service_server(t_service* tservice) { if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends(), true, true); extends_processor = extends + ".TProcessorImpl"; - indent(s_service) << "TProcessorImpl = class(" << extends_processor << ", IProcessor)" << endl; + indent(s_service) << "TProcessorImpl = class(" << extends_processor << ", IProcessor)" << '\n'; } else { - indent(s_service) << "TProcessorImpl = class( TInterfacedObject, IProcessor)" << endl; + indent(s_service) << "TProcessorImpl = class( TInterfacedObject, IProcessor)" << '\n'; } - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "constructor Create( iface_: Iface );" << endl; - indent(s_service) << "destructor Destroy; override;" << endl; + indent(s_service) << "constructor Create( iface_: Iface );" << '\n'; + indent(s_service) << "destructor Destroy; override;" << '\n'; indent_down(); - indent_impl(s_service_impl) << "constructor " << full_cls << ".Create( iface_: Iface );" << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "constructor " << full_cls << ".Create( iface_: Iface );" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); if (tservice->get_extends() != nullptr) { - indent_impl(s_service_impl) << "inherited Create( iface_);" << endl; + indent_impl(s_service_impl) << "inherited Create( iface_);" << '\n'; } else { - indent_impl(s_service_impl) << "inherited Create;" << endl; + indent_impl(s_service_impl) << "inherited Create;" << '\n'; } - indent_impl(s_service_impl) << "Self.iface_ := iface_;" << endl; + indent_impl(s_service_impl) << "Self.iface_ := iface_;" << '\n'; if (tservice->get_extends() != nullptr) { - indent_impl(s_service_impl) << "ASSERT( processMap_ <> nil); // inherited" << endl; + indent_impl(s_service_impl) << "ASSERT( processMap_ <> nil); // inherited" << '\n'; } else { indent_impl(s_service_impl) - << "processMap_ := TThriftDictionaryImpl.Create;" << endl; + << "processMap_ := TThriftDictionaryImpl.Create;" << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent_impl(s_service_impl) << "processMap_.AddOrSetValue( '" << (*f_iter)->get_name() << "', " - << (*f_iter)->get_name() << "_Process);" << endl; + << (*f_iter)->get_name() << "_Process);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; - indent_impl(s_service_impl) << "destructor " << full_cls << ".Destroy;" << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "destructor " << full_cls << ".Destroy;" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "inherited;" << endl; + indent_impl(s_service_impl) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; - indent(s_service) << "private" << endl; + indent(s_service) << "private" << '\n'; indent_up(); - indent(s_service) << "iface_: Iface;" << endl; + indent(s_service) << "iface_: Iface;" << '\n'; indent_down(); if (tservice->get_extends() == nullptr) { - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "type" << endl; + indent(s_service) << "type" << '\n'; indent_up(); indent(s_service) << "TProcessFunction = reference to procedure( seqid: System.Integer; const iprot: " "IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; indent_down(); indent_down(); - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "processMap_: IThriftDictionary;" << endl; + indent(s_service) << "processMap_: IThriftDictionary;" << '\n'; indent_down(); } - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); if (extends.empty()) { indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const " - "events : IProcessorEvents): System.Boolean;" << endl; + "events : IProcessorEvents): System.Boolean;" << '\n'; } else { indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const " - "events : IProcessorEvents): System.Boolean; reintroduce;" << endl; + "events : IProcessorEvents): System.Boolean; reintroduce;" << '\n'; } indent_impl(s_service_impl) << "function " << full_cls << ".Process( const iprot: IProtocol; " "const oprot: IProtocol; const events " - ": IProcessorEvents): System.Boolean;" << endl; + ": IProcessorEvents): System.Boolean;" << '\n'; ; - indent_impl(s_service_impl) << "var" << endl; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << endl; - indent_impl(s_service_impl) << "fn : TProcessFunction;" << endl; - indent_impl(s_service_impl) << "x : TApplicationException;" << endl; + indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << '\n'; + indent_impl(s_service_impl) << "fn : TProcessFunction;" << '\n'; + indent_impl(s_service_impl) << "x : TApplicationException;" << '\n'; if (events_) { - indent_impl(s_service_impl) << "context : IRequestEvents;" << endl; + indent_impl(s_service_impl) << "context : IRequestEvents;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "msg := iprot.ReadMessageBegin();" << endl; - indent_impl(s_service_impl) << "fn := nil;" << endl; - indent_impl(s_service_impl) << "if not processMap_.TryGetValue(msg.Name, fn)" << endl; - indent_impl(s_service_impl) << "or not Assigned(fn) then begin" << endl; + indent_impl(s_service_impl) << "msg := iprot.ReadMessageBegin();" << '\n'; + indent_impl(s_service_impl) << "fn := nil;" << '\n'; + indent_impl(s_service_impl) << "if not processMap_.TryGetValue(msg.Name, fn)" << '\n'; + indent_impl(s_service_impl) << "or not Assigned(fn) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << endl; - indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << '\n'; + indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << '\n'; indent_impl(s_service_impl) << "x := " "TApplicationExceptionUnknownMethod.Create(" - "'Invalid method name: ''' + msg.Name + '''');" << endl; + "'Invalid method name: ''' + msg.Name + '''');" << '\n'; indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, msg.Name, TMessageType.Exception, msg.SeqID);" - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl; - indent_impl(s_service_impl) << "x.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; - indent_impl(s_service_impl) << "Result := True;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << '\n'; + indent_impl(s_service_impl) << "x.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; + indent_impl(s_service_impl) << "Result := True;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil" << endl; - indent_impl(s_service_impl) << "then context := events.CreateRequestContext(msg.Name)" << endl; - indent_impl(s_service_impl) << "else context := nil;" << endl; - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "if events <> nil" << '\n'; + indent_impl(s_service_impl) << "then context := events.CreateRequestContext(msg.Name)" << '\n'; + indent_impl(s_service_impl) << "else context := nil;" << '\n'; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot, context);" << endl; + indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot, context);" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "finally" << endl; + indent_impl(s_service_impl) << "finally" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "if context <> nil then begin" << endl; + indent_impl(s_service_impl) << "if context <> nil then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "context.CleanupContext;" << endl; - indent_impl(s_service_impl) << "context := nil;" << endl; + indent_impl(s_service_impl) << "context.CleanupContext;" << '\n'; + indent_impl(s_service_impl) << "context := nil;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } else { - indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot);" << endl; + indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "except" << endl; + indent_impl(s_service_impl) << "except" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "on TTransportExceptionTimedOut do begin" << endl; + indent_impl(s_service_impl) << "on TTransportExceptionTimedOut do begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := True;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Result := True;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; - indent_impl(s_service_impl) << "else begin" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; + indent_impl(s_service_impl) << "else begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := False;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Result := False;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; - indent_impl(s_service_impl) << "Result := True;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; + indent_impl(s_service_impl) << "Result := True;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_function_helpers(t_function* tfunction) { @@ -2420,18 +2420,21 @@ void t_delphi_generator::generate_function_helpers(t_function* tfunction) { result.append(&success); } + int num_excepts = 0; t_struct* xs = tfunction->get_xceptions(); const vector& fields = xs->get_members(); vector::const_iterator f_iter; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { result.append(*f_iter); + ++num_excepts; } + result.set_method_xcepts(num_excepts > 0); - generate_delphi_struct_definition(s_service, &result, false, true, true); + generate_delphi_struct_definition(s_service, &result); generate_delphi_struct_impl(s_service_impl, normalize_clsnm(service_name_, "T") + ".", &result, - false); + true, false); } void t_delphi_generator::generate_process_function(t_service* tservice, t_function* tfunction) { @@ -2449,46 +2452,46 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi indent(s_service) << "procedure " << funcname << "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; if (tfunction->is_oneway()) { - indent_impl(s_service_impl) << "// one way processor" << endl; + indent_impl(s_service_impl) << "// one way processor" << '\n'; } else { - indent_impl(s_service_impl) << "// both way processor" << endl; + indent_impl(s_service_impl) << "// both way processor" << '\n'; } indent_impl(s_service_impl) << "procedure " << full_cls << "." << funcname << "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; - indent_impl(s_service_impl) << "var" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "args: " << args_intfnm << ";" << endl; + indent_impl(s_service_impl) << "args: " << args_intfnm << ";" << '\n'; if (!tfunction->is_oneway()) { - indent_impl(s_service_impl) << "msg: Thrift.Protocol.TThriftMessage;" << endl; - indent_impl(s_service_impl) << "ret: " << result_intfnm << ";" << endl; - indent_impl(s_service_impl) << "appx : TApplicationException;" << endl; + indent_impl(s_service_impl) << "msg: Thrift.Protocol.TThriftMessage;" << '\n'; + indent_impl(s_service_impl) << "ret: " << result_intfnm << ";" << '\n'; + indent_impl(s_service_impl) << "appx : TApplicationException;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); if (!tfunction->is_oneway()) { - indent_impl(s_service_impl) << "ret := " << result_clsnm << "Impl.Create;" << endl; + indent_impl(s_service_impl) << "ret := " << result_clsnm << "Impl.Create;" << '\n'; } - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreRead;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreRead;" << '\n'; } - indent_impl(s_service_impl) << "args := " << args_clsnm << "Impl.Create;" << endl; - indent_impl(s_service_impl) << "args.Read(iprot);" << endl; - indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << "args := " << args_clsnm << "Impl.Create;" << '\n'; + indent_impl(s_service_impl) << "args.Read(iprot);" << '\n'; + indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostRead;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostRead;" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -2513,88 +2516,85 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi } s_service_impl << "args." << prop_name(*f_iter); } - s_service_impl << ");" << endl; + s_service_impl << ");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent_impl(s_service_impl) << "args." << prop_name(*f_iter) - << " := " << empty_value((*f_iter)->get_type()) << ";" << endl; + << " := " << empty_value((*f_iter)->get_type()) << ";" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "except" << endl; + indent_impl(s_service_impl) << "except" << '\n'; indent_up_impl(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent_impl(s_service_impl) << "on E: " << type_name((*x_iter)->get_type(), true, true) - << " do begin" << endl; + << " do begin" << '\n'; indent_up_impl(); if (!tfunction->is_oneway()) { - string factory_name = normalize_clsnm((*x_iter)->get_type()->get_name(), "", true) - + "Factory"; - indent_impl(s_service_impl) << "ret." << prop_name(*x_iter) << " := E." << factory_name << ";" - << endl; + indent_impl(s_service_impl) << "ret." << prop_name(*x_iter) << " := E.ExceptionData;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } - indent_impl(s_service_impl) << "on E: Exception do begin" << endl; + indent_impl(s_service_impl) << "on E: Exception do begin" << '\n'; indent_up_impl(); if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << '\n'; } if (!tfunction->is_oneway()) { indent_impl(s_service_impl) << "appx := TApplicationExceptionInternalError.Create(E.Message);" - << endl; - indent_impl(s_service_impl) << "try" << endl; + << '\n'; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << '\n'; } indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '" << tfunction->get_name() << "', TMessageType.Exception, seqid);" - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl; - indent_impl(s_service_impl) << "appx.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << '\n'; + indent_impl(s_service_impl) << "appx.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << '\n'; } - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "finally" << endl; + indent_impl(s_service_impl) << "finally" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "appx.Free;" << endl; + indent_impl(s_service_impl) << "appx.Free;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; if (!tfunction->is_oneway()) { if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << '\n'; } indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '" << tfunction->get_name() << "', TMessageType.Reply, seqid); " - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg); " << endl; - indent_impl(s_service_impl) << "ret.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg); " << '\n'; + indent_impl(s_service_impl) << "ret.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << '\n'; } } else if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.OnewayComplete;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.OnewayComplete;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_deserialize_field(ostream& out, @@ -2602,10 +2602,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, ostream& local_vars) { - t_type* type = tfield->get_type(); - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + t_type* type = tfield->get_type()->get_true_type(); if (type->is_void()) { throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name(); @@ -2634,11 +2631,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, break; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - out << "ReadAnsiString();"; - } else { - out << (com_types_ ? "ReadBinaryCOM();" : "ReadBinary();"); - } + out << (com_types_ ? "ReadBinaryCOM();" : "ReadBinary();"); } else { out << "ReadString();"; } @@ -2671,7 +2664,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, out << "ReadI32()"; out << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2685,14 +2678,10 @@ void t_delphi_generator::generate_deserialize_struct(ostream& out, string prefix) { string typ_name; - if (tstruct->is_xception()) { - typ_name = type_name(tstruct, true, false, true, true); - } else { - typ_name = type_name(tstruct, true, false); - } + typ_name = type_name(tstruct, true, false); - indent_impl(out) << prefix << name << " := " << typ_name << ".Create;" << endl; - indent_impl(out) << prefix << name << ".Read(iprot);" << endl; + indent_impl(out) << prefix << name << " := " << typ_name << ".Create;" << '\n'; + indent_impl(out) << prefix << name << ".Read(iprot);" << '\n'; } void t_delphi_generator::generate_deserialize_container(ostream& out, @@ -2720,22 +2709,22 @@ void t_delphi_generator::generate_deserialize_container(ostream& out, } else if (ttype->is_list()) { local_var = obj + ": TThriftList;"; } - local_vars << " " << local_var << endl; + local_vars << " " << local_var << '\n'; counter = tmp("_i"); local_var = counter + ": System.Integer;"; - local_vars << " " << local_var << endl; + local_vars << " " << local_var << '\n'; - indent_impl(out) << name << " := " << type_name(ttype, true) << ".Create;" << endl; + indent_impl(out) << name << " := " << type_name(ttype, true) << ".Create;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << obj << " := iprot.ReadMapBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << obj << " := iprot.ReadSetBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << obj << " := iprot.ReadListBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadListBegin();" << '\n'; } - indent_impl(out) << "for " << counter << " := 0 to " << obj << ".Count - 1 do begin" << endl; + indent_impl(out) << "for " << counter << " := 0 to " << obj << ".Count - 1 do begin" << '\n'; indent_up_impl(); if (ttype->is_map()) { generate_deserialize_map_element(out, is_xception, (t_map*)ttype, name, local_vars); @@ -2745,14 +2734,14 @@ void t_delphi_generator::generate_deserialize_container(ostream& out, generate_deserialize_list_element(out, is_xception, (t_list*)ttype, name, local_vars); } indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << "iprot.ReadMapEnd();" << endl; + indent_impl(out) << "iprot.ReadMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << "iprot.ReadSetEnd();" << endl; + indent_impl(out) << "iprot.ReadSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << "iprot.ReadListEnd();" << endl; + indent_impl(out) << "iprot.ReadListEnd();" << '\n'; } } @@ -2769,13 +2758,13 @@ void t_delphi_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - local_vars << " " << declare_field(&fkey) << endl; - local_vars << " " << declare_field(&fval) << endl; + local_vars << " " << declare_field(&fkey) << '\n'; + local_vars << " " << declare_field(&fval) << '\n'; generate_deserialize_field(out, is_xception, &fkey, "", local_vars); generate_deserialize_field(out, is_xception, &fval, "", local_vars); - indent_impl(out) << prefix << ".AddOrSetValue( " << key << ", " << val << ");" << endl; + indent_impl(out) << prefix << ".AddOrSetValue( " << key << ", " << val << ");" << '\n'; } void t_delphi_generator::generate_deserialize_set_element(ostream& out, @@ -2785,9 +2774,9 @@ void t_delphi_generator::generate_deserialize_set_element(ostream& out, ostream& local_vars) { string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - local_vars << " " << declare_field(&felem) << endl; + local_vars << " " << declare_field(&felem) << '\n'; generate_deserialize_field(out, is_xception, &felem, "", local_vars); - indent_impl(out) << prefix << ".Add(" << elem << ");" << endl; + indent_impl(out) << prefix << ".Add(" << elem << ");" << '\n'; } void t_delphi_generator::generate_deserialize_list_element(ostream& out, @@ -2797,9 +2786,9 @@ void t_delphi_generator::generate_deserialize_list_element(ostream& out, ostream& local_vars) { string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - local_vars << " " << declare_field(&felem) << endl; + local_vars << " " << declare_field(&felem) << '\n'; generate_deserialize_field(out, is_xception, &felem, "", local_vars); - indent_impl(out) << prefix << ".Add(" << elem << ");" << endl; + indent_impl(out) << prefix << ".Add(" << elem << ");" << '\n'; } void t_delphi_generator::generate_serialize_field(ostream& out, @@ -2809,10 +2798,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, ostream& local_vars) { (void)local_vars; - t_type* type = tfield->get_type(); - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + t_type* type = tfield->get_type()->get_true_type(); string name = prefix + prop_name(tfield, is_xception); @@ -2837,11 +2823,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, break; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - out << "WriteAnsiString("; - } else { - out << "WriteBinary("; - } + out << "WriteBinary("; } else { out << "WriteString("; } @@ -2874,7 +2856,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, } else if (type->is_enum()) { out << "WriteI32(System.Integer(" << name << "));"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2889,7 +2871,7 @@ void t_delphi_generator::generate_serialize_struct(ostream& out, ostream& local_vars) { (void)local_vars; (void)tstruct; - out << indent_impl() << prefix << ".Write(oprot);" << endl; + out << indent_impl() << prefix << ".Write(oprot);" << '\n'; } void t_delphi_generator::generate_serialize_container(ostream& out, @@ -2900,42 +2882,42 @@ void t_delphi_generator::generate_serialize_container(ostream& out, string obj; if (ttype->is_map()) { obj = tmp("map"); - local_vars << " " << obj << " : TThriftMap;" << endl; + local_vars << " " << obj << " : TThriftMap;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteMapBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteMapBegin( " << obj << ");" << '\n'; } else if (ttype->is_set()) { obj = tmp("set_"); - local_vars << " " << obj << " : TThriftSet;" << endl; + local_vars << " " << obj << " : TThriftSet;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteSetBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteSetBegin( " << obj << ");" << '\n'; } else if (ttype->is_list()) { obj = tmp("list_"); - local_vars << " " << obj << " : TThriftList;" << endl; + local_vars << " " << obj << " : TThriftList;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteListBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteListBegin( " << obj << ");" << '\n'; } string iter = tmp("_iter"); if (ttype->is_map()) { - local_vars << " " << iter << ": " << type_name(((t_map*)ttype)->get_key_type()) << ";" << endl; - indent_impl(out) << "for " << iter << " in " << prefix << ".Keys do begin" << endl; + local_vars << " " << iter << ": " << type_name(((t_map*)ttype)->get_key_type()) << ";" << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << ".Keys do begin" << '\n'; indent_up_impl(); } else if (ttype->is_set()) { local_vars << " " << iter << ": " << type_name(((t_set*)ttype)->get_elem_type()) << ";" - << endl; - indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << endl; + << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << '\n'; indent_up_impl(); } else if (ttype->is_list()) { local_vars << " " << iter << ": " << type_name(((t_list*)ttype)->get_elem_type()) << ";" - << endl; - indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << endl; + << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << '\n'; indent_up_impl(); } @@ -2948,14 +2930,14 @@ void t_delphi_generator::generate_serialize_container(ostream& out, } indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << "oprot.WriteMapEnd();" << endl; + indent_impl(out) << "oprot.WriteMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << "oprot.WriteSetEnd();" << endl; + indent_impl(out) << "oprot.WriteSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << "oprot.WriteListEnd();" << endl; + indent_impl(out) << "oprot.WriteListEnd();" << '\n'; } } @@ -2993,24 +2975,24 @@ void t_delphi_generator::generate_property(ostream& out, t_field* tfield, bool isPublic, bool is_xception) { - generate_delphi_property(out, is_xception, tfield, isPublic, "Get"); + generate_delphi_property(out, is_xception, tfield, isPublic); } void t_delphi_generator::generate_delphi_property(ostream& out, bool struct_is_xception, t_field* tfield, - bool isPublic, - std::string fieldPrefix) { + bool isPublic) { (void)isPublic; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); generate_delphi_doc(out, tfield); indent(out) << "property " << prop_name(tfield, struct_is_xception) << ": " - << type_name(ftype, false, true, is_xception, true) - << " read " << prop_name(tfield, struct_is_xception, fieldPrefix) - << " write " << prop_name(tfield, struct_is_xception, "Set") - << ";" << endl; + << type_name(ftype, false, true/*, false, true*/) + << " read " << prop_name(tfield, struct_is_xception, "Get") + << " write " << prop_name(tfield, struct_is_xception, "Set") + << ";" + << render_deprecation_attribute(tfield->annotations_, " {", "}") + << '\n'; } std::string t_delphi_generator::prop_name(t_field* tfield, bool is_xception, std::string prefix) { @@ -3042,9 +3024,7 @@ string t_delphi_generator::normalize_clsnm(string clsnm, string prefix, bool b_n string t_delphi_generator::type_name(t_type* ttype, bool b_cls, - bool b_no_postfix, - bool b_exception_factory, - bool b_full_exception_factory) { + bool b_no_postfix) { if (ttype->is_typedef()) { t_typedef* tdef = (t_typedef*)ttype; @@ -3052,9 +3032,7 @@ string t_delphi_generator::type_name(t_type* ttype, if (tdef->get_type() != nullptr) { return type_name(tdef->get_type(), b_cls, - b_no_postfix, - b_exception_factory, - b_full_exception_factory); + b_no_postfix); } else { throw "unresolved forward declaration: " + tdef->get_symbolic(); } @@ -3109,20 +3087,12 @@ string t_delphi_generator::type_name(t_type* ttype, string nm = normalize_clsnm(ttype->get_name(), type_prefix); - if (b_exception_factory) { - nm = nm + "Factory"; - } - if (b_cls) { if (!b_no_postfix) { nm = nm + "Impl"; } } - if (b_exception_factory && b_full_exception_factory) { - return type_name(ttype, true, true, false, false) + "." + nm; - } - return nm; } @@ -3180,8 +3150,6 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) { return ""; case t_base_type::TYPE_STRING: if (tbase->is_binary()) { - if (ansistr_binary_) - return "System.AnsiString"; if( com_types_) return "IThriftBytes"; if( rtti_) @@ -3211,16 +3179,13 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) { } string t_delphi_generator::declare_field(t_field* tfield, - bool init, std::string prefix, bool is_xception_class) { - (void)init; - t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); string result = prop_name(tfield, is_xception_class, prefix) + ": " - + type_name(ftype, false, true, is_xception, true) + ";"; + + type_name(ftype, false, true) + ";"; + return result; } @@ -3237,7 +3202,7 @@ string t_delphi_generator::function_signature(t_function* tfunction, } string signature = ""; - + if( for_async) { if (is_void(ttype)) { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async(" @@ -3245,7 +3210,7 @@ string t_delphi_generator::function_signature(t_function* tfunction, } else { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async(" + argument_list(tfunction->get_arglist()) + "): IFuture<" - + type_name(ttype, false, true, is_xception, true) + ">;"; + + type_name(ttype, false, true/*, is_xception, true*/) + ">;"; } } else { if (is_void(ttype)) { @@ -3254,21 +3219,13 @@ string t_delphi_generator::function_signature(t_function* tfunction, } else { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "(" + argument_list(tfunction->get_arglist()) + "): " - + type_name(ttype, false, true, is_xception, true) + ";"; + + type_name(ttype, false, true/*, is_xception, true*/) + ";"; } } // deprecated method? only at intf decl! if( full_cls == "") { - auto iter = tfunction->annotations_.find("deprecated"); - if( tfunction->annotations_.end() != iter && !iter->second.empty()) { - signature += " deprecated"; - // empty annotation values end up with "1" somewhere, ignore these as well - if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { - signature += " " + make_pascal_string_literal(iter->second.back()); - } - signature += ";"; - } + signature += render_deprecation_attribute(tfunction->annotations_, " ", ";"); } return signature; @@ -3291,7 +3248,7 @@ string t_delphi_generator::argument_list(t_struct* tstruct) { tt = (*f_iter)->get_type(); result += input_arg_prefix(tt); // const? result += normalize_name((*f_iter)->get_name()) + ": " - + type_name(tt, false, true, tt->is_xception(), true); + + type_name(tt, false, true/*, tt->is_xception(), true*/); } return result; } @@ -3316,10 +3273,10 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c if (line.size() > 80) { if (firstline) { - result << endl << newline_indent; + result << '\n' << newline_indent; firstline = false; } - result << line << endl; + result << line << '\n'; line = newline_indent; } else if (line.size() > 0) { line += " "; @@ -3328,7 +3285,7 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c tt = (*f_iter)->get_type(); line += input_arg_prefix(tt); // const? line += constructor_param_name((*f_iter)->get_name()) + ": " - + type_name(tt, false, true, tt->is_xception(), true); + + type_name(tt, false, true/*, tt->is_xception(), true*/); } if (line.size() > 0) { @@ -3347,9 +3304,7 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c } string t_delphi_generator::type_to_enum(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -3389,9 +3344,7 @@ string t_delphi_generator::type_to_enum(t_type* type) { } string t_delphi_generator::empty_value(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -3400,11 +3353,7 @@ string t_delphi_generator::empty_value(t_type* type) { return "0"; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - return "''"; - } else { - return "nil"; - } + return "nil"; } else { return "''"; } @@ -3439,28 +3388,30 @@ void t_delphi_generator::generate_delphi_property_writer_definition(ostream& out t_field* tfield, bool is_xception_class) { t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent(out) << "procedure " << prop_name(tfield, is_xception_class, "Set") - << "( const Value: " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; + << "( const Value: " << type_name(ftype, false, true/*, false, true*/) << ");" + << render_deprecation_attribute(tfield->annotations_, " ", ";") + << '\n'; } void t_delphi_generator::generate_delphi_property_reader_definition(ostream& out, t_field* tfield, bool is_xception_class) { t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent(out) << "function " << prop_name(tfield, is_xception_class, "Get") << ": " - << type_name(ftype, false, true, is_xception, true) << ";" << endl; + << type_name(ftype, false, true/*, false*/) << ";" + << render_deprecation_attribute(tfield->annotations_, " ", ";") + << '\n'; } void t_delphi_generator::generate_delphi_isset_reader_writer_definition(ostream& out, t_field* tfield, bool is_xception) { - indent(out) << "function " << prop_name(tfield, is_xception,"Get__isset_") << ": System.Boolean;" << endl; - indent(out) << "procedure " << prop_name(tfield, is_xception, "Set__isset_") << "( const value : System.Boolean);" << endl; + (void)is_xception; + indent(out) << "function " << prop_name(tfield, false,"Get__isset_") << ": System.Boolean;" << '\n'; + indent(out) << "procedure " << prop_name(tfield, false, "Set__isset_") << "( const value : System.Boolean);" << '\n'; } void t_delphi_generator::generate_delphi_clear_union_value(ostream& out, @@ -3470,28 +3421,22 @@ void t_delphi_generator::generate_delphi_clear_union_value(ostream& out, t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name) { + bool is_union) { (void)cls_prefix; (void)name; (void)type; (void)is_union; - (void)is_xception_factory; - (void)xception_factory_name; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); - indent_impl(out) << "if " << prop_name(tfield, is_xception_class,"F__isset_") << " then begin" - << endl; + indent_impl(out) << "if " << prop_name(tfield, is_xception_class,"F__isset_") << " then begin" << '\n'; indent_up_impl(); - indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := False;" << endl; + indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := False;" << '\n'; indent_impl(out) << prop_name(tfield, is_xception_class,fieldPrefix) << " := " - << "Default( " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; + << "Default( " << type_name(ftype, false, true/*, is_xception, true*/) << ");" + << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; } void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out, @@ -3501,35 +3446,31 @@ void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out, t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name) { + bool is_union) { (void)type; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent_impl(out) << "procedure " << cls_prefix << name << "." << prop_name(tfield, is_xception_class,"Set") - << "( const Value: " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; - indent_impl(out) << "begin" << endl; + << "( const Value: " << type_name(ftype, false, true) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); if (is_union) { - indent_impl(out) << "ClearUnionValues;" << endl; + indent_impl(out) << "ClearUnionValues;" << '\n'; } - if (tfield->get_req() != t_field::T_REQUIRED) { - indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := True;" << endl; - } - indent_impl(out) << prop_name(tfield, is_xception_class,fieldPrefix) << " := Value;" << endl; - - if (is_xception_class && (!is_xception_factory)) { - indent_impl(out) << xception_factory_name << "." << prop_name(tfield, is_xception_class) - << " := Value;" << endl; + if(is_xception_class) { + indent_impl(out) << "FData." << prop_name(tfield, false, fieldPrefix) << " := Value;" << '\n'; + } else { + if (tfield->get_req() != t_field::T_REQUIRED) { + indent_impl(out) << prop_name(tfield, is_xception_class, "F__isset_") << " := True;" << '\n'; + } + indent_impl(out) << prop_name(tfield, is_xception_class, fieldPrefix) << " := Value;" << '\n'; } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_property_reader_impl(ostream& out, @@ -3542,17 +3483,19 @@ void t_delphi_generator::generate_delphi_property_reader_impl(ostream& out, (void)type; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent_impl(out) << "function " << cls_prefix << name << "." << prop_name(tfield, is_xception_class,"Get") << ": " - << type_name(ftype, false, true, is_xception, true) << ";" << endl; - indent_impl(out) << "begin" << endl; + << type_name(ftype, false, true) << ";" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << "Result := " << prop_name(tfield, is_xception_class,fieldPrefix) << ";" - << endl; + if(is_xception_class) { + indent_impl(out) << "Result := FData." << prop_name(tfield, false, fieldPrefix) << ";" << '\n'; + } else { + indent_impl(out) << "Result := " << prop_name(tfield, is_xception_class, fieldPrefix) << ";" << '\n'; + } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_isset_reader_writer_impl(ostream& out, @@ -3561,76 +3504,41 @@ void t_delphi_generator::generate_delphi_isset_reader_writer_impl(ostream& out, t_type* type, t_field* tfield, std::string fieldPrefix, - bool is_xception) { + bool is_xception_class) { (void)type; - string isset_name = prop_name(tfield, is_xception, "__isset_"); - + string isset_name = prop_name(tfield, false, "__isset_"); + indent_impl(out) << "function " << cls_prefix << name << "." - << "Get" << isset_name << ": System.Boolean;" << endl; - indent_impl(out) << "begin" << endl; + << "Get" << isset_name << ": System.Boolean;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << "Result := " << fieldPrefix << isset_name << ";" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - - indent_impl(out) << "procedure " << cls_prefix << name << "." - << "Set" << isset_name << "( const value: System.Boolean);" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << fieldPrefix << isset_name << " := value;" << endl; + if(is_xception_class) { + indent_impl(out) << "Result := FData." << fieldPrefix << isset_name << ";" << '\n'; + } else { + indent_impl(out) << "Result := " << fieldPrefix << isset_name << ";" << '\n'; + } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; -} - -void t_delphi_generator::generate_delphi_create_exception_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception) { - (void)cls_prefix; - - string exception_cls_nm = type_name(tstruct, true, true); - string cls_nm = type_name(tstruct, true, false, is_exception, is_exception); + indent_impl(out) << "end;" << '\n' << '\n'; - indent_impl(out) << "function " << cls_nm << ".CreateException: " << exception_cls_nm << ";" - << endl; - - indent_impl(out) << "begin" << endl; + indent_impl(out) << "procedure " << cls_prefix << name << "." + << "Set" << isset_name << "( const value: System.Boolean);" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - - indent_impl(out) << "Result := " << exception_cls_nm << ".Create;" << endl; - string factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; - indent_impl(out) << "Result.F" << factory_name << " := Self;" << endl; - - const vector& fields = tstruct->get_members(); - vector::const_iterator f_iter; - - string propname; - - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - propname = prop_name(*f_iter, is_exception); - if ((*f_iter)->get_req() != t_field::T_REQUIRED) { - indent_impl(out) << "if " << prop_name(*f_iter, is_exception,"__isset_") << " then begin" << endl; - indent_up_impl(); - } - indent_impl(out) << "Result." << propname << " := " << propname << ";" << endl; - if ((*f_iter)->get_req() != t_field::T_REQUIRED) { - indent_down_impl(); - indent_impl(out) << "end;" << endl; - } + if(is_xception_class) { + indent_impl(out) << "FData." << fieldPrefix << isset_name << " := value;" << '\n'; + } else { + indent_impl(out) << fieldPrefix << isset_name << " := value;" << '\n'; } - - indent_impl(out) << "Result.UpdateMessageProperty;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } + void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { ostringstream local_vars; ostringstream code_block; @@ -3638,53 +3546,53 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent_impl(code_block) << "begin" << endl; + indent_impl(code_block) << "begin" << '\n'; indent_up_impl(); - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := iprot.NextRecursionLevel;" << endl; + indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << '\n'; + indent_impl(code_block) << "tracker := iprot.NextRecursionLevel;" << '\n'; // local bools for required fields for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { indent_impl(local_vars) << prop_name(*f_iter, is_exception,"_req_isset_") << " : System.Boolean;" - << endl; + << '\n'; indent_impl(code_block) << prop_name(*f_iter, is_exception,"_req_isset_") << " := FALSE;" - << endl; + << '\n'; } } - indent_impl(code_block) << "struc := iprot.ReadStructBegin;" << endl; + indent_impl(code_block) << "struc := iprot.ReadStructBegin;" << '\n'; - indent_impl(code_block) << "try" << endl; + indent_impl(code_block) << "try" << '\n'; indent_up_impl(); - indent_impl(code_block) << "while (true) do begin" << endl; + indent_impl(code_block) << "while (true) do begin" << '\n'; indent_up_impl(); - indent_impl(code_block) << "field_ := iprot.ReadFieldBegin();" << endl; + indent_impl(code_block) << "field_ := iprot.ReadFieldBegin();" << '\n'; - indent_impl(code_block) << "if (field_.Type_ = TType.Stop) then Break;" << endl; + indent_impl(code_block) << "if (field_.Type_ = TType.Stop) then Break;" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { - code_block << endl; - indent_impl(code_block) << "case field_.ID of" << endl; + code_block << '\n'; + indent_impl(code_block) << "case field_.ID of" << '\n'; indent_up_impl(); } first = false; if (f_iter != fields.begin()) { - code_block << endl; + code_block << '\n'; } - indent_impl(code_block) << (*f_iter)->get_key() << ": begin" << endl; + indent_impl(code_block) << (*f_iter)->get_key() << ": begin" << '\n'; indent_up_impl(); indent_impl(code_block) << "if (field_.Type_ = " << type_to_enum((*f_iter)->get_type()) - << ") then begin" << endl; + << ") then begin" << '\n'; indent_up_impl(); generate_deserialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); @@ -3692,155 +3600,88 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, // required field? if ((*f_iter)->get_req() == t_field::T_REQUIRED) { indent_impl(code_block) << prop_name(*f_iter, is_exception,"_req_isset_") << " := TRUE;" - << endl; + << '\n'; } indent_down_impl(); - indent_impl(code_block) << "end else begin" << endl; + indent_impl(code_block) << "end else begin" << '\n'; indent_up_impl(); - indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << endl; + indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; indent_down_impl(); indent_impl(code_block) << "end;"; } if (!first) { - code_block << endl; + code_block << '\n'; indent_down_impl(); - indent_impl(code_block) << "else" << endl; + indent_impl(code_block) << "else" << '\n'; indent_up_impl(); } - indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << endl; + indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << '\n'; if (!first) { indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; } - indent_impl(code_block) << "iprot.ReadFieldEnd;" << endl; + indent_impl(code_block) << "iprot.ReadFieldEnd;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "finally" << endl; + indent_impl(code_block) << "finally" << '\n'; indent_up_impl(); - indent_impl(code_block) << "iprot.ReadStructEnd;" << endl; + indent_impl(code_block) << "iprot.ReadStructEnd;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; // all required fields have been read? first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if(first) { - code_block << endl; + code_block << '\n'; first = false; } - indent_impl(code_block) << "if not " << prop_name(*f_iter, is_exception,"_req_isset_") << endl; + indent_impl(code_block) << "if not " << prop_name(*f_iter, is_exception,"_req_isset_") << '\n'; indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create(" << "'required field " << prop_name(*f_iter, is_exception) << " not set');" - << endl; + << '\n'; } } - - if( is_exception && (!is_x_factory)) { - code_block << endl; - indent_impl(code_block) << "UpdateMessageProperty;" << endl; - } - indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; - - string cls_nm; - - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); - indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Read( const iprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; - indent_up_impl(); - indent_impl(out) << "field_ : TThriftField;" << endl; - indent_impl(out) << "struc : TThriftStruct;" << endl; - indent_down_impl(); - out << local_vars.str() << endl; - out << code_block.str(); -} - -void t_delphi_generator::generate_delphi_struct_result_writer_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_x_factory) { - - ostringstream local_vars; - ostringstream code_block; - - string name = tstruct->get_name(); - const vector& fields = tstruct->get_sorted_members(); - vector::const_iterator f_iter; - - indent_impl(code_block) << "begin" << endl; - indent_up_impl(); - - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl; - - indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl; - indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl; - - if (fields.size() > 0) { - indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl; - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent_impl(code_block) << "if (" << prop_name(*f_iter, is_exception,"__isset_") << ") then" - << endl; - indent_impl(code_block) << "begin" << endl; - indent_up_impl(); - indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << endl; - indent_impl(code_block) << "field_.Type_ := " << type_to_enum((*f_iter)->get_type()) << ";" - << endl; - indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl; - indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl; - generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); - indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl; - indent_down_impl(); - } + if( is_exception) { + code_block << '\n'; + indent_impl(code_block) << "UpdateMessageProperty;" << '\n'; } - - indent_impl(code_block) << "oprot.WriteFieldStop();" << endl; - indent_impl(code_block) << "oprot.WriteStructEnd();" << endl; - indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; + indent_impl(code_block) << "end;" << '\n' << '\n'; string cls_nm; - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); + cls_nm = type_name(tstruct, true, is_exception); - indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Write( const oprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; + indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Read( const iprot: IProtocol);" << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << "struc : TThriftStruct;" << endl; - - if (fields.size() > 0) { - indent_impl(out) << "field_ : TThriftField;" << endl; - } - - out << local_vars.str(); + indent_impl(out) << "field_ : TThriftField;" << '\n'; + indent_impl(out) << "struc : TThriftStruct;" << '\n'; indent_down_impl(); + out << local_vars.str() << '\n'; out << code_block.str(); } void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { ostringstream local_vars; ostringstream code_block; @@ -3849,17 +3690,17 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent_impl(code_block) << "begin" << endl; + indent_impl(code_block) << "begin" << '\n'; indent_up_impl(); - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl; + indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << '\n'; + indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << '\n'; - indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl; - indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl; + indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << '\n'; + indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << '\n'; if (fields.size() > 0) { - indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl; + indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << '\n'; } for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -3870,54 +3711,54 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, bool has_isset = (!is_required); if (is_required && null_allowed) { null_allowed = false; - indent_impl(code_block) << "if (Self." << fieldname << " = nil)" << endl; + indent_impl(code_block) << "if (Self." << fieldname << " = nil)" << '\n'; indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create(" << "'required field " << fieldname << " not set');" - << endl; + << '\n'; } if (null_allowed) { indent_impl(code_block) << "if (Self." << fieldname << " <> nil)"; if (has_isset) { code_block << " and " << isset_name; } - code_block << " then begin" << endl; + code_block << " then begin" << '\n'; indent_up_impl(); } else { if (has_isset) { - indent_impl(code_block) << "if (" << isset_name << ") then begin" << endl; + indent_impl(code_block) << "if (" << isset_name << ") then begin" << '\n'; indent_up_impl(); } } - indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << endl; + indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << '\n'; indent_impl(code_block) << "field_.Type_ := " << type_to_enum((*f_iter)->get_type()) << ";" - << endl; - indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl; - indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl; + << '\n'; + indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << '\n'; + indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << '\n'; generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); - indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl; + indent_impl(code_block) << "oprot.WriteFieldEnd();" << '\n'; if (null_allowed || has_isset) { indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; } } - indent_impl(code_block) << "oprot.WriteFieldStop();" << endl; - indent_impl(code_block) << "oprot.WriteStructEnd();" << endl; + indent_impl(code_block) << "oprot.WriteFieldStop();" << '\n'; + indent_impl(code_block) << "oprot.WriteStructEnd();" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; + indent_impl(code_block) << "end;" << '\n' << '\n'; string cls_nm; - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); + cls_nm = type_name(tstruct, true, is_exception); indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Write( const oprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; + << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << "struc : TThriftStruct;" << endl; + indent_impl(out) << "struc : TThriftStruct;" << '\n'; if (fields.size() > 0) { - indent_impl(out) << "field_ : TThriftField;" << endl; + indent_impl(out) << "field_ : TThriftField;" << '\n'; } out << local_vars.str(); indent_down_impl(); @@ -3927,8 +3768,7 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -3936,7 +3776,7 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string cls_nm; if (is_exception) { - cls_nm = type_name(tstruct, true, (!is_x_factory), is_x_factory, true); + cls_nm = type_name(tstruct, true, true/*, false, true*/); } else { cls_nm = type_name(tstruct, true, false); } @@ -3945,28 +3785,28 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string tmp_first = tmp("_first"); bool useFirstFlag = false; - indent_impl(out) << "function " << cls_prefix << cls_nm << ".ToString: string;" << endl; - indent_impl(out) << "var" << endl; + indent_impl(out) << "function " << cls_prefix << cls_nm << ".ToString: string;" << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << " : TThriftStringBuilder;" << endl; + indent_impl(out) << tmp_sb << " : TThriftStringBuilder;" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool is_optional = ((*f_iter)->get_req() != t_field::T_REQUIRED); if (is_optional) { - indent_impl(out) << tmp_first << " : System.Boolean;" << endl; + indent_impl(out) << tmp_first << " : System.Boolean;" << '\n'; useFirstFlag = true; } break; } indent_down_impl(); - indent_impl(out) << "begin" << endl; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << " := TThriftStringBuilder.Create('(');" << endl; - indent_impl(out) << "try" << endl; + indent_impl(out) << tmp_sb << " := TThriftStringBuilder.Create('(');" << '\n'; + indent_impl(out) << "try" << '\n'; indent_up_impl(); if (useFirstFlag) { - indent_impl(out) << tmp_first << " := TRUE;" << endl; + indent_impl(out) << tmp_first << " := TRUE;" << '\n'; } bool had_required = false; // set to true after first required field has been processed @@ -3979,53 +3819,50 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, if (is_optional) { out << " and " << prop_name(*f_iter, is_exception,"__isset_"); } - out << " then begin" << endl; + out << " then begin" << '\n'; indent_up_impl(); } else { if (is_optional) { indent_impl(out) << "if (" << prop_name(*f_iter, is_exception, "__isset_") << ") then begin" - << endl; + << '\n'; indent_up_impl(); } } if (useFirstFlag && (!had_required)) { - indent_impl(out) << "if not " << tmp_first << " then " << tmp_sb << ".Append(',');" << endl; + indent_impl(out) << "if not " << tmp_first << " then " << tmp_sb << ".Append(',');" << '\n'; if (is_optional) { - indent_impl(out) << tmp_first << " := FALSE;" << endl; + indent_impl(out) << tmp_first << " := FALSE;" << '\n'; } indent_impl(out) << tmp_sb << ".Append('" << prop_name((*f_iter), is_exception) << ": ');" - << endl; + << '\n'; } else { indent_impl(out) << tmp_sb << ".Append(', " << prop_name((*f_iter), is_exception) << ": ');" - << endl; + << '\n'; } - t_type* ttype = (*f_iter)->get_type(); - while (ttype->is_typedef()) { - ttype = ((t_typedef*)ttype)->get_type(); - } + t_type* ttype = (*f_iter)->get_type()->get_true_type(); if (ttype->is_xception() || ttype->is_struct()) { indent_impl(out) << "if (Self." << prop_name((*f_iter), is_exception) << " = nil) then " << tmp_sb << ".Append('') else " << tmp_sb << ".Append( Self." - << prop_name((*f_iter), is_exception) << ".ToString());" << endl; + << prop_name((*f_iter), is_exception) << ".ToString());" << '\n'; } else if (ttype->is_enum()) { - indent_impl(out) << tmp_sb << ".Append(EnumUtils<" - << type_name(ttype, false, true, false, false) - << ">.ToString( System.Ord( Self." - << prop_name((*f_iter), is_exception) << ")));" << endl; + indent_impl(out) << tmp_sb << ".Append(EnumUtils<" + << type_name(ttype, false, true) + << ">.ToString( System.Ord( Self." + << prop_name((*f_iter), is_exception) << ")));" << '\n'; } else if (ttype->is_uuid()) { indent_impl(out) << tmp_sb << ".Append( GUIDToString(Self." << prop_name((*f_iter), is_exception) << "));" - << endl; + << '\n'; } else { indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");" - << endl; + << '\n'; } if (null_allowed || is_optional) { indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; } if (!is_optional) { @@ -4033,27 +3870,25 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, } } - indent_impl(out) << tmp_sb << ".Append(')');" << endl; - indent_impl(out) << "Result := " << tmp_sb << ".ToString;" << endl; + indent_impl(out) << tmp_sb << ".Append(')');" << '\n'; + indent_impl(out) << "Result := " << tmp_sb << ".ToString;" << '\n'; if (useFirstFlag) { - indent_impl(out) << "if " << tmp_first << " then {prevent warning};" << endl; + indent_impl(out) << "if " << tmp_first << " then {prevent warning};" << '\n'; } indent_down_impl(); - indent_impl(out) << "finally" << endl; + indent_impl(out) << "finally" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << ".Free;" << endl; + indent_impl(out) << tmp_sb << ".Free;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } bool t_delphi_generator::is_void(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -4069,10 +3904,36 @@ std::string t_delphi_generator::display_name() const { } +bool t_delphi_generator::is_deprecated(std::map>& annotations) +{ + auto iter = annotations.find("deprecated"); + return (annotations.end() != iter); +} + +std::string t_delphi_generator::render_deprecation_attribute(std::map>& annotations, std::string prefix, std::string postfix) +{ + std::string result = ""; + auto iter = annotations.find("deprecated"); + if( annotations.end() != iter) { + result += prefix; + result += "deprecated"; + + // empty annotation values end up with "1" somewhere, ignore these as well + if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { + result += " " + make_pascal_string_literal(iter->second.back()); + } + + result += postfix; + } + return result; +} + + + + THRIFT_REGISTER_GENERATOR( delphi, "Delphi", - " ansistr_binary: Use AnsiString for binary datatype (default is TBytes).\n" " register_types: Enable TypeRegistry, allows for creation of struct, union\n" " and container instances by interface or TypeInfo()\n" " constprefix: Name TConstants classes after IDL to reduce ambiguities\n" diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc index 72939729668..37810a99320 100644 --- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc @@ -39,7 +39,20 @@ using std::string; using std::stringstream; using std::vector; -static const std::string endl = "\n"; // avoid ostream << std::endl flushes +/** + * Helper enum for string mapping + */ +enum class StringTo {String, Binary, Both}; + +/** + * Helper enum for sets mapping + */ +enum class SetsTo {V1, V2}; + +/** + * Helper enum for type declaration + */ +enum class TypeDeclaraion {Type, Nominal}; /** * Erlang code generator. @@ -60,6 +73,9 @@ class t_erl_generator : public t_generator { maps_ = false; export_lines_first_ = true; export_types_lines_first_ = true; + string_to_ = StringTo::Both; + sets_to_ = SetsTo::V1; + type_declaration_ = TypeDeclaraion::Type; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { if( iter->first.compare("legacynames") == 0) { @@ -70,6 +86,35 @@ class t_erl_generator : public t_generator { delimiter_ = iter->second; } else if( iter->first.compare("app_prefix") == 0) { app_prefix_ = iter->second; + } else if( iter->first.compare("string") == 0) { + auto string_to_value = iter->second; + if( string_to_value.compare("string") == 0) { + string_to_ = StringTo::String; + } else if( string_to_value.compare("binary") == 0) { + string_to_ = StringTo::Binary; + } else if( string_to_value.compare("both") == 0) { + string_to_ = StringTo::Both; + } else { + throw "unknown string option value:" + string_to_value; + } + } else if( iter->first.compare("set") == 0) { + auto set_to_value = iter->second; + if( set_to_value.compare("v1") == 0) { + sets_to_ = SetsTo::V1; + } else if( set_to_value.compare("v2") == 0) { + sets_to_ = SetsTo::V2; + } else { + throw "unknown set option value:" + set_to_value; + } + } else if( iter->first.compare("type") == 0) { + auto type_to_value = iter->second; + if( type_to_value.compare("type") == 0) { + type_declaration_ = TypeDeclaraion::Type; + } else if( type_to_value.compare("nominal") == 0) { + type_declaration_ = TypeDeclaraion::Nominal; + } else { + throw "unknown type option value:" + type_to_value; + } } else { throw "unknown option erl:" + iter->first; } @@ -103,10 +148,20 @@ class t_erl_generator : public t_generator { std::string render_member_value(t_field* field); std::string render_member_requiredness(t_field* field); + std::string render_typedef_type(t_typedef* ttypedef); + + std::string render_type(t_type* type); + std::string render_base_type(t_type* type); + std::string render_string_type(); + std::string render_type_declaration(); + std::string render_const_name(std::string name); + std::string render_const_name(std::string sname, std::string name); + // std::string render_default_value(t_type* type); std::string render_default_value(t_field* field); std::string render_const_value(t_type* type, t_const_value* value); std::string render_type_term(t_type* ttype, bool expand_structs, bool extended_info = false); + std::string render_default_sets_value(); /** * Struct generation code @@ -142,6 +197,7 @@ class t_erl_generator : public t_generator { std::string render_includes(); std::string type_name(t_type* ttype); std::string render_const_list_values(t_type* type, t_const_value* value); + std::string render_const_string_value(t_const_value* value); std::string function_signature(t_function* tfunction, std::string prefix = ""); @@ -190,6 +246,15 @@ class t_erl_generator : public t_generator { /* used to avoid module name clashes for different applications */ std::string app_prefix_; + /* string type definition strategy */ + StringTo string_to_; + + /* sets type definition strategy */ + SetsTo sets_to_; + + /* type declaration strategy */ + TypeDeclaraion type_declaration_; + /** * add function to export list */ @@ -268,14 +333,14 @@ void t_erl_generator::init_generator() { hrl_header(f_types_hrl_file_, program_module_name + "_types"); - f_types_file_ << erl_autogen_comment() << endl - << "-module(" << program_module_name << "_types)." << endl - << erl_imports() << endl; + f_types_file_ << erl_autogen_comment() << '\n' + << "-module(" << program_module_name << "_types)." << '\n' + << erl_imports() << '\n'; - f_types_file_ << "-include(\"" << program_module_name << "_types.hrl\")." << endl - << endl; + f_types_file_ << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' + << '\n'; - f_types_hrl_file_ << render_includes() << endl; + f_types_hrl_file_ << render_includes() << '\n'; // consts files string f_consts_name = get_out_dir() + program_module_name + "_constants.erl"; @@ -284,28 +349,28 @@ void t_erl_generator::init_generator() { f_consts_file_.open(f_consts_name.c_str()); f_consts_hrl_file_.open(f_consts_hrl_name.c_str()); - f_consts_file_ << erl_autogen_comment() << endl - << "-module(" << program_module_name << "_constants)." << endl - << erl_imports() << endl - << "-include(\"" << program_module_name << "_types.hrl\")." << endl - << endl; + f_consts_file_ << erl_autogen_comment() << '\n' + << "-module(" << program_module_name << "_constants)." << '\n' + << erl_imports() << '\n' + << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' + << '\n'; - f_consts_hrl_file_ << erl_autogen_comment() << endl << erl_imports() << endl - << "-include(\"" << program_module_name << "_types.hrl\")." << endl << endl; + f_consts_hrl_file_ << erl_autogen_comment() << '\n' << erl_imports() << '\n' + << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' << '\n'; } /** * Boilerplate at beginning and end of header files */ void t_erl_generator::hrl_header(ostream& out, string name) { - out << erl_autogen_comment() << endl - << "-ifndef(_" << name << "_included)." << endl << "-define(_" << name << "_included, yeah)." - << endl; + out << erl_autogen_comment() << '\n' + << "-ifndef(_" << name << "_included)." << '\n' << "-define(_" << name << "_included, yeah)." + << '\n'; } void t_erl_generator::hrl_footer(ostream& out, string name) { (void)name; - out << "-endif." << endl; + out << "-endif." << '\n'; } /** @@ -365,13 +430,13 @@ void t_erl_generator::close_generator() { export_types_string("struct_names", 0); export_types_string("exception_names", 0); - f_types_file_ << "-export([" << export_types_lines_.str() << "])." << endl << endl; + f_types_file_ << "-export([" << export_types_lines_.str() << "])." << '\n' << '\n'; f_types_file_ << f_info_.str(); - f_types_file_ << "struct_info(_) -> erlang:error(function_clause)." << endl << endl; + f_types_file_ << "struct_info(_) -> erlang:error(function_clause)." << '\n' << '\n'; f_types_file_ << f_info_ext_.str(); - f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << endl << endl; + f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << '\n' << '\n'; generate_const_functions(); @@ -439,12 +504,13 @@ void t_erl_generator::generate_type_metadata(std::string function_name, vector constants = tenum->get_constants(); vector::iterator c_iter; + vector const_names; + vector::iterator names_iter; v_enums_.push_back(tenum); v_enum_names_.push_back(atomify(tenum->get_name())); + f_types_hrl_file_ << "%% enum " << tenum->get_name() << "\n" << "\n"; + for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); string name = (*c_iter)->get_name(); - indent(f_types_hrl_file_) << "-define(" << constify(make_safe_for_module_name(program_name_)) - << "_" << constify(tenum->get_name()) << "_" << constify(name) << ", " - << value << ")." << endl; + string const_name = render_const_name(tenum->get_name(), name); + indent(f_types_hrl_file_) << "-define(" << const_name << ", " << value << ")." << '\n'; + const_names.push_back(const_name); + } + f_types_hrl_file_ << '\n'; + + string enum_definition = render_type_declaration() + type_name(tenum) + "() :: "; + string value_indent(enum_definition.size(), ' '); + f_types_hrl_file_ << enum_definition; + bool names_iter_first = false; + for (names_iter = const_names.begin(); names_iter != const_names.end(); ++names_iter) { + if (names_iter_first) { + f_types_hrl_file_ << " |" << "\n" << value_indent; + } else { + names_iter_first = true; + } + indent(f_types_hrl_file_) << "?" << *names_iter; } + f_types_hrl_file_ << ".\n" << "\n"; +} + +string t_erl_generator::render_const_name(std::string name) { + return constify(make_safe_for_module_name(program_name_)) + "_" + constify(name); +} - f_types_hrl_file_ << endl; +string t_erl_generator::render_const_name(std::string sname, std::string name) { + return render_const_name(sname) + "_" + constify(name); } void t_erl_generator::generate_enum_info(t_enum* tenum){ @@ -551,7 +642,7 @@ void t_erl_generator::generate_enum_info(t_enum* tenum){ } indent_down(); } - f_types_file_ << "\n"; + f_types_file_ << '\n'; indent(f_types_file_) << "];\n\n"; indent_down(); } @@ -578,8 +669,8 @@ void t_erl_generator::generate_const(t_const* tconst) { // Save the tconst so that function can be emitted in generate_const_functions(). v_consts_.push_back(tconst); - f_consts_hrl_file_ << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_" - << constify(name) << ", " << render_const_value(type, value) << ")." << endl << endl; + f_consts_hrl_file_ << "-define(" << render_const_name(name) << ", " + << render_const_value(type, value) << ")." << '\n' << '\n'; } /** @@ -595,7 +686,7 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { case t_base_type::TYPE_STRING: - out << '"' << get_escaped_string(value) << '"'; + out << render_const_string_value(value); break; case t_base_type::TYPE_BOOL: out << (value->get_integer() > 0 ? "true" : "false"); @@ -617,7 +708,8 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) { throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - indent(out) << value->get_integer(); + string name = (((t_enum*)type)->get_constant_by_value(value->get_integer()))->get_name(); + indent(out) << "?" << render_const_name(type->get_name(), name); } else if (type->is_struct() || type->is_xception()) { out << "#" << type_name(type) << "{"; @@ -678,7 +770,11 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) { out << ","; } } - out << "])"; + out << "]"; + if (sets_to_ == SetsTo::V2) { + out << ", [{version, 2}]"; + } + out << ")"; } else if (type->is_list()) { out << "[" << render_const_list_values(type, value) << "]"; } else { @@ -705,6 +801,13 @@ string t_erl_generator::render_const_list_values(t_type* type, t_const_value* va return out.str(); } +string t_erl_generator::render_const_string_value(t_const_value* constval) { + if (string_to_ == StringTo::Binary) { + return "<<\"" + get_escaped_string(constval) + "\">>"; + } + return '"' + get_escaped_string(constval) + '"'; +} + string t_erl_generator::render_default_value(t_field* field) { t_type* type = field->get_type(); @@ -717,7 +820,7 @@ string t_erl_generator::render_default_value(t_field* field) { return "dict:new()"; } } else if (type->is_set()) { - return "sets:new()"; + return render_default_sets_value(); } else if (type->is_list()) { return "[]"; } else { @@ -725,32 +828,32 @@ string t_erl_generator::render_default_value(t_field* field) { } } +string t_erl_generator::render_default_sets_value() { + switch (sets_to_) { + case SetsTo::V1: + return "sets:new()"; + case SetsTo::V2: + return "sets:new([{version,2}])"; + default: + throw "compiler error: unsupported set type"; + } +} + string t_erl_generator::render_member_type(t_field* field) { - t_type* type = get_true_type(field->get_type()); + t_type* type = field->get_type(); + return render_type(type); +} + +string t_erl_generator::render_type(t_type* type) { if (type->is_base_type()) { - t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - switch (tbase) { - case t_base_type::TYPE_STRING: - return "string() | binary()"; - case t_base_type::TYPE_BOOL: - return "boolean()"; - case t_base_type::TYPE_I8: - case t_base_type::TYPE_I16: - case t_base_type::TYPE_I32: - case t_base_type::TYPE_I64: - return "integer()"; - case t_base_type::TYPE_DOUBLE: - return "float()"; - default: - throw "compiler error: unsupported base type " + t_base_type::t_base_name(tbase); - } + return render_base_type(type); } else if (type->is_enum()) { - return "integer()"; - } else if (type->is_struct() || type->is_xception()) { + return type_name(type) + "()"; + } else if (type->is_struct() || type->is_xception() || type->is_typedef()) { return type_name(type) + "()"; } else if (type->is_map()) { if (maps_) { - return "map()"; + return "maps:map()"; } else { return "dict:dict()"; } @@ -763,6 +866,49 @@ string t_erl_generator::render_member_type(t_field* field) { } } +string t_erl_generator::render_base_type(t_type* type) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + switch (tbase) { + case t_base_type::TYPE_STRING: + return render_string_type(); + case t_base_type::TYPE_BOOL: + return "boolean()"; + case t_base_type::TYPE_I8: + case t_base_type::TYPE_I16: + case t_base_type::TYPE_I32: + case t_base_type::TYPE_I64: + return "integer()"; + case t_base_type::TYPE_DOUBLE: + return "float()"; + default: + throw "compiler error: unsupported base type " + t_base_type::t_base_name(tbase); + } +} + +string t_erl_generator::render_string_type() { + switch (string_to_) { + case StringTo::String: + return "string()"; + case StringTo::Binary: + return "binary()"; + case StringTo::Both: + return "string() | binary()"; + default: + throw "compiler error: unsupported string type"; + } +} + +string t_erl_generator::render_type_declaration() { + switch (type_declaration_) { + case TypeDeclaraion::Type: + return "-type "; + case TypeDeclaraion::Nominal: + return "-nominal "; + default: + throw "compiler error: unsupported type declaration"; + } +} + string t_erl_generator::render_member_requiredness(t_field* field) { switch (field->get_req()) { case t_field::T_REQUIRED: @@ -774,6 +920,11 @@ string t_erl_generator::render_member_requiredness(t_field* field) { } } +string t_erl_generator::render_typedef_type(t_typedef* ttypedef) { + t_type* type = ttypedef->get_type(); + return render_type(type); +} + /** * Generates a struct */ @@ -809,7 +960,15 @@ void t_erl_generator::generate_erl_struct(t_struct* tstruct, bool is_exception) * @param tstruct The struct definition */ void t_erl_generator::generate_erl_struct_definition(ostream& out, t_struct* tstruct) { - indent(out) << "%% struct " << type_name(tstruct) << endl << endl; + indent(out) << "%% "; + if (tstruct->is_union()) { + out << "union "; + } else if (tstruct->is_xception()) { + out << "exception "; + } else { + out << "struct "; + } + out << tstruct->get_name() << '\n' << '\n'; std::stringstream buf; buf << indent() << "-record(" << type_name(tstruct) << ", {"; @@ -819,13 +978,14 @@ void t_erl_generator::generate_erl_struct_definition(ostream& out, t_struct* tst for (vector::const_iterator m_iter = members.begin(); m_iter != members.end();) { generate_erl_struct_member(buf, *m_iter); if (++m_iter != members.end()) { - buf << "," << endl << field_indent; + buf << "," << '\n' << field_indent; } } buf << "})."; - out << buf.str() << endl; - out << "-type " + type_name(tstruct) << "() :: #" + type_name(tstruct) + "{}." << endl << endl; + out << buf.str() << '\n'; + out << render_type_declaration() << type_name(tstruct) + << "() :: #" + type_name(tstruct) + "{}." << '\n' << '\n'; } /** @@ -871,19 +1031,19 @@ string t_erl_generator::render_member_value(t_field* field) { * Generates the read method for a struct */ void t_erl_generator::generate_erl_struct_info(ostream& out, t_struct* tstruct) { - indent(out) << "struct_info(" << type_name(tstruct) << ") ->" << endl; + indent(out) << "struct_info(" << type_name(tstruct) << ") ->" << '\n'; indent_up(); - out << indent() << render_type_term(tstruct, true) << ";" << endl; + out << indent() << render_type_term(tstruct, true) << ";" << '\n'; indent_down(); - out << endl; + out << '\n'; } void t_erl_generator::generate_erl_extended_struct_info(ostream& out, t_struct* tstruct) { - indent(out) << "struct_info_ext(" << type_name(tstruct) << ") ->" << endl; + indent(out) << "struct_info_ext(" << type_name(tstruct) << ") ->" << '\n'; indent_up(); - out << indent() << render_type_term(tstruct, true, true) << ";" << endl; + out << indent() << render_type_term(tstruct, true, true) << ";" << '\n'; indent_down(); - out << endl; + out << '\n'; } /** @@ -909,11 +1069,11 @@ void t_erl_generator::generate_service(t_service* tservice) { if (tservice->get_extends() != nullptr) { f_service_hrl_ << "-include(\"" << make_safe_for_module_name(tservice->get_extends()->get_name()) - << "_thrift.hrl\"). % inherit " << endl; + << "_thrift.hrl\"). % inherit " << '\n'; } f_service_hrl_ << "-include(\"" << make_safe_for_module_name(program_name_) << "_types.hrl\")." - << endl << endl; + << '\n' << '\n'; // Generate the three main parts of the service (well, two for now in PHP) generate_service_helpers(tservice); // cpiro: New Erlang Order @@ -924,13 +1084,13 @@ void t_erl_generator::generate_service(t_service* tservice) { // indent_down(); - f_service_file_ << erl_autogen_comment() << endl << "-module(" << service_name_ << "_thrift)." - << endl << "-behaviour(thrift_service)." << endl << endl << erl_imports() << endl; + f_service_file_ << erl_autogen_comment() << '\n' << "-module(" << service_name_ << "_thrift)." + << '\n' << "-behaviour(thrift_service)." << '\n' << '\n' << erl_imports() << '\n'; f_service_file_ << "-include(\"" << make_safe_for_module_name(tservice->get_name()) - << "_thrift.hrl\")." << endl << endl; + << "_thrift.hrl\")." << '\n' << '\n'; - f_service_file_ << "-export([" << export_lines_.str() << "])." << endl << endl; + f_service_file_ << "-export([" << export_lines_.str() << "])." << '\n' << '\n'; f_service_file_ << f_service_.str(); @@ -946,7 +1106,7 @@ void t_erl_generator::generate_service_metadata(t_service* tservice) { vector functions = tservice->get_functions(); size_t num_functions = functions.size(); - indent(f_service_) << "function_names() -> " << endl; + indent(f_service_) << "function_names() -> " << '\n'; indent_up(); indent(f_service_) << "["; @@ -972,14 +1132,14 @@ void t_erl_generator::generate_service_helpers(t_service* tservice) { vector::iterator f_iter; // indent(f_service_) << - // "% HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + // "% HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; export_string("struct_info", 1); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_erl_function_helpers(*f_iter); } - f_service_ << "struct_info(_) -> erlang:error(function_clause)." << endl; + f_service_ << "struct_info(_) -> erlang:error(function_clause)." << '\n'; } /** @@ -1002,26 +1162,26 @@ void t_erl_generator::generate_service_interface(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "%%% interface" << endl; + f_service_ << "%%% interface" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << indent() << "% " << function_signature(*f_iter) << endl; + f_service_ << indent() << "% " << function_signature(*f_iter) << '\n'; generate_function_info(tservice, *f_iter); } // Inheritance - pass unknown functions to base class if (tservice->get_extends() != nullptr) { - indent(f_service_) << "function_info(Function, InfoType) ->" << endl; + indent(f_service_) << "function_info(Function, InfoType) ->" << '\n'; indent_up(); indent(f_service_) << make_safe_for_module_name(tservice->get_extends()->get_name()) - << "_thrift:function_info(Function, InfoType)." << endl; + << "_thrift:function_info(Function, InfoType)." << '\n'; indent_down(); } else { // return function_clause error for non-existent functions - indent(f_service_) << "function_info(_Func, _Info) -> erlang:error(function_clause)." << endl; + indent(f_service_) << "function_info(_Func, _Info) -> erlang:error(function_clause)." << '\n'; } - indent(f_service_) << endl; + indent(f_service_) << '\n'; } /** @@ -1036,30 +1196,30 @@ void t_erl_generator::generate_function_info(t_service* tservice, t_function* tf t_struct* arg_struct = tfunction->get_arglist(); // function_info(Function, params_type): - indent(f_service_) << "function_info(" << name_atom << ", params_type) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", params_type) ->" << '\n'; indent_up(); - indent(f_service_) << render_type_term(arg_struct, true) << ";" << endl; + indent(f_service_) << render_type_term(arg_struct, true) << ";" << '\n'; indent_down(); // function_info(Function, reply_type): - indent(f_service_) << "function_info(" << name_atom << ", reply_type) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", reply_type) ->" << '\n'; indent_up(); if (!tfunction->get_returntype()->is_void()) - indent(f_service_) << render_type_term(tfunction->get_returntype(), false) << ";" << endl; + indent(f_service_) << render_type_term(tfunction->get_returntype(), false) << ";" << '\n'; else if (tfunction->is_oneway()) - indent(f_service_) << "oneway_void;" << endl; + indent(f_service_) << "oneway_void;" << '\n'; else indent(f_service_) << "{struct, []}" - << ";" << endl; + << ";" << '\n'; indent_down(); // function_info(Function, exceptions): - indent(f_service_) << "function_info(" << name_atom << ", exceptions) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", exceptions) ->" << '\n'; indent_up(); - indent(f_service_) << render_type_term(xs, true) << ";" << endl; + indent(f_service_) << render_type_term(xs, true) << ";" << '\n'; indent_down(); } @@ -1246,11 +1406,11 @@ std::string t_erl_generator::render_type_term(t_type* type, } if (++i != end) { - buf << "," << endl << field_indent; + buf << "," << '\n' << field_indent; } } - buf << "]}" << endl; + buf << "]}" << '\n'; return buf.str(); } else { return "{struct, {" + atomify(type_module(type)) + ", " + type_name(type) + "}}"; @@ -1292,4 +1452,7 @@ THRIFT_REGISTER_GENERATOR( " legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n" " delimiter= Delimiter between namespace prefix and record name. Default is '.'.\n" " app_prefix= Application prefix for generated Erlang files.\n" - " maps: Generate maps instead of dicts.\n") + " maps: Generate maps instead of dicts.\n" + " string= Define string as 'string', 'binary' or 'both'. Default is 'both'.\n" + " set= Define sets implementation, supported 'v1' and 'v2'. Default is 'v1'.\n" + " type= Define type declaration, supported 'type' and 'nominal'. Default is 'type'.\n") diff --git a/compiler/cpp/src/thrift/generate/t_generator.cc b/compiler/cpp/src/thrift/generate/t_generator.cc index 970281e74cf..217cf8ab9ec 100644 --- a/compiler/cpp/src/thrift/generate/t_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_generator.cc @@ -77,8 +77,8 @@ void t_generator::generate_program() { } std::set t_generator::lang_keywords_for_validation() const { - // Nothing by default. It makes no sense to restrict the whole world to use non-PHP keywords only. - // Override on a per-generator(!) basis if you cannot live without it, e.g. that particular language has no + // Nothing by default. It makes no sense to restrict the whole world to use non-PHP keywords only. + // Override on a per-generator(!) basis if you cannot live without it, e.g. that particular language has no // mechanism or way to deal with it properly, so we absolutely need to fail on it as the last possible resort. return {}; } @@ -101,35 +101,43 @@ void t_generator::validate(const vector& list) const{ void t_generator::validate(t_function const* f) const { validate_id(f->get_name()); + f->validate(); validate(f->get_arglist()); validate(f->get_xceptions()); } void t_generator::validate(t_service const* s) const { validate_id(s->get_name()); + s->validate(); validate(s->get_functions()); } void t_generator::validate(t_enum const* en) const { validate_id(en->get_name()); + en->validate(); validate(en->get_constants()); } void t_generator::validate(t_struct const* s) const { validate_id(s->get_name()); + s->validate(); validate(s->get_members()); } void t_generator::validate(t_enum_value const* en_val) const { validate_id(en_val->get_name()); + en_val->validate(); } void t_generator::validate(t_typedef const* td) const { validate_id(td->get_name()); + td->validate(); } void t_generator::validate(t_const const* c) const { validate_id(c->get_name()); + c->validate(); } void t_generator::validate(t_field const* f) const { validate_id(f->get_name()); + f->validate(); } void t_generator::validate_id(const string& id) const { @@ -172,11 +180,11 @@ void t_generator::generate_docstring_comment(ostream& out, docs.getline(line, 1024); if (strlen(line) > 0) { - indent(out) << line_prefix << line << std::endl; + indent(out) << line_prefix << line << '\n'; } else if (line_prefix.empty()){ - out << std::endl; + out << '\n'; } else if(!docs.eof()) { - indent(out) << line_prefix << std::endl; + indent(out) << line_prefix << '\n'; } } if (!comment_end.empty()) diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc index db30c8bae8c..bef28553632 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc @@ -518,7 +518,7 @@ void t_go_generator::init_generator() { f_consts_ << go_autogen_comment() << go_package() << render_includes(true); - f_const_values_ << endl << "func init() {" << endl; + f_const_values_ << '\n' << "func init() {" << '\n'; // Create file for the GoUnusedProtection__ variable string f_unused_prot_name_ = package_dir_ + "/" + "GoUnusedProtection__.go"; @@ -706,6 +706,7 @@ string t_go_generator::go_imports_begin(bool consts) { } system_packages.push_back("errors"); system_packages.push_back("fmt"); + system_packages.push_back("iter"); system_packages.push_back("log/slog"); system_packages.push_back("time"); // For the thrift import, always do rename import to make sure it's called thrift. @@ -731,6 +732,7 @@ string t_go_generator::go_imports_end() { "var _ = context.Background\n" "var _ = errors.New\n" "var _ = fmt.Printf\n" + "var _ = iter.Pull[int]\n" "var _ = slog.Log\n" "var _ = time.Now\n" "var _ = thrift.ZERO\n" @@ -744,7 +746,7 @@ string t_go_generator::go_imports_end() { * Closes the type files */ void t_go_generator::close_generator() { - f_const_values_ << "}" << endl << endl; + f_const_values_ << "}" << '\n' << '\n'; f_consts_ << f_const_values_.str(); // Close types and constants files @@ -768,11 +770,13 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) { return; } - f_types_ << "type " << new_type_name << " " << base_type << endl << endl; + generate_deprecation_comment(f_types_, ttypedef->annotations_); + f_types_ << "type " << new_type_name << " " << base_type << '\n' << '\n'; // Generate a convenience function that converts an instance of a type // (which may be a constant) into a pointer to an instance of a type. + generate_deprecation_comment(f_types_, ttypedef->annotations_); f_types_ << "func " << new_type_name << "Ptr(v " << new_type_name << ") *" << new_type_name - << " { return &v }" << endl << endl; + << " { return &v }" << '\n' << '\n'; } /** @@ -782,90 +786,142 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_go_generator::generate_enum(t_enum* tenum) { - std::ostringstream to_string_mapping, from_string_mapping; + std::ostringstream to_string_mapping, from_string_mapping, known_values_mapping; std::string tenum_name(publicize(tenum->get_name())); generate_go_docstring(f_types_, tenum); - f_types_ << "type " << tenum_name << " int64" << endl << "const (" << endl; + generate_deprecation_comment(f_types_, tenum->annotations_); + f_types_ << "type " << tenum_name << " int64" << '\n' << '\n' << "const (" << '\n'; - to_string_mapping << indent() << "func (p " << tenum_name << ") String() string {" << endl; - to_string_mapping << indent() << " switch p {" << endl; + known_values_mapping << indent() << "var known" << tenum_name << "Values" << " = []" << tenum_name << "{" << '\n'; + to_string_mapping << indent() << "func (p " << tenum_name << ") String() string {" << '\n'; + indent_up(); + to_string_mapping << indent() << "switch p {" << '\n'; + indent_down(); + + generate_deprecation_comment(from_string_mapping, tenum->annotations_); from_string_mapping << indent() << "func " << tenum_name << "FromString(s string) (" << tenum_name - << ", error) {" << endl; - from_string_mapping << indent() << " switch s {" << endl; + << ", error) {" << '\n'; + indent_up(); + from_string_mapping << indent() << "switch s {" << '\n'; + indent_down(); vector constants = tenum->get_constants(); vector::iterator c_iter; int value = -1; + indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { value = (*c_iter)->get_value(); string iter_std_name(escape_string((*c_iter)->get_name())); string iter_name((*c_iter)->get_name()); - f_types_ << indent() << " " << tenum_name << "_" << iter_name << ' ' << tenum_name << " = " - << value << endl; + generate_deprecation_comment(f_types_, (*c_iter)->annotations_); + f_types_ << indent() << tenum_name << "_" << iter_name << ' ' << tenum_name << " = " + << value << '\n'; + known_values_mapping << indent() << tenum_name << "_" << iter_name << "," << '\n'; // Dictionaries to/from string names of enums - to_string_mapping << indent() << " case " << tenum_name << "_" << iter_name << ": return \"" - << iter_std_name << "\"" << endl; + to_string_mapping << indent() << "case " << tenum_name << "_" << iter_name << ": return \"" + << iter_std_name << "\"" << '\n'; if (iter_std_name != escape_string(iter_name)) { - from_string_mapping << indent() << " case \"" << iter_std_name << "\", \"" + from_string_mapping << indent() << "case \"" << iter_std_name << "\", \"" << escape_string(iter_name) << "\": return " << tenum_name << "_" - << iter_name << ", nil " << endl; + << iter_name << ", nil" << '\n'; } else { - from_string_mapping << indent() << " case \"" << iter_std_name << "\": return " << tenum_name - << "_" << iter_name << ", nil " << endl; + from_string_mapping << indent() << "case \"" << iter_std_name << "\": return " << tenum_name + << "_" << iter_name << ", nil" << '\n'; } } - to_string_mapping << indent() << " }" << endl; - to_string_mapping << indent() << " return \"\"" << endl; - to_string_mapping << indent() << "}" << endl; - from_string_mapping << indent() << " }" << endl; - from_string_mapping << indent() << " return " << tenum_name << "(0)," - << " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << endl; - from_string_mapping << indent() << "}" << endl; + to_string_mapping << indent() << "}" << '\n'; + to_string_mapping << indent() << "return \"\"" << '\n'; + indent_down(); + to_string_mapping << indent() << "}" << '\n'; + indent_up(); + from_string_mapping << indent() << "}" << '\n'; + from_string_mapping << indent() << "return " << tenum_name << "(0)," + << " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << '\n'; + indent_down(); + from_string_mapping << indent() << "}" << '\n'; + + known_values_mapping << indent() << "}" << '\n' << '\n'; + known_values_mapping << indent() << "func " << tenum_name << "Values() iter.Seq[" << tenum_name << "] {" << '\n'; + indent_up(); + known_values_mapping << indent() << "return func(yield func(" << tenum_name << ") bool) {" << '\n'; + indent_up(); + known_values_mapping << indent() << "for _, v := range known" << tenum_name << "Values {" << '\n'; + indent_up(); + known_values_mapping << indent() << "if !yield(v) {" << '\n'; + indent_up(); + known_values_mapping << indent() << "return" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; - f_types_ << ")" << endl << endl << to_string_mapping.str() << endl << from_string_mapping.str() - << endl << endl; + f_types_ << ")" << '\n' << '\n' + << known_values_mapping.str() << '\n' + << to_string_mapping.str() << '\n' + << from_string_mapping.str() << '\n' << '\n'; // Generate a convenience function that converts an instance of an enum // (which may be a constant) into a pointer to an instance of that enum // type. + generate_deprecation_comment(f_types_, tenum->annotations_); f_types_ << "func " << tenum_name << "Ptr(v " << tenum_name << ") *" << tenum_name - << " { return &v }" << endl << endl; + << " { return &v }" << '\n' << '\n'; // Generate MarshalText - f_types_ << "func (p " << tenum_name << ") MarshalText() ([]byte, error) {" << endl; - f_types_ << "return []byte(p.String()), nil" << endl; - f_types_ << "}" << endl << endl; + f_types_ << "func (p " << tenum_name << ") MarshalText() ([]byte, error) {" << '\n'; + indent_up(); + f_types_ << indent() << "return []byte(p.String()), nil" << '\n'; + indent_down(); + f_types_ << "}" << '\n' << '\n'; // Generate UnmarshalText - f_types_ << "func (p *" << tenum_name << ") UnmarshalText(text []byte) error {" << endl; - f_types_ << "q, err := " << tenum_name << "FromString(string(text))" << endl; - f_types_ << "if (err != nil) {" << endl << "return err" << endl << "}" << endl; - f_types_ << "*p = q" << endl; - f_types_ << "return nil" << endl; - f_types_ << "}" << endl << endl; + f_types_ << "func (p *" << tenum_name << ") UnmarshalText(text []byte) error {" << '\n'; + indent_up(); + f_types_ << indent() << "q, err := " << tenum_name << "FromString(string(text))" << '\n'; + f_types_ << indent() << "if err != nil {" << '\n'; + indent_up(); + f_types_ << indent() << "return err" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "*p = q" << '\n'; + f_types_ << indent() << "return nil" << '\n'; + indent_down(); + f_types_ << "}" << '\n' << '\n'; // Generate Scan for sql.Scanner interface - f_types_ << "func (p *" << tenum_name << ") Scan(value interface{}) error {" <get_name()); t_const_value* value = tconst->get_value(); if (type->is_enum() || (type->is_base_type() && ((t_base_type*)type)->get_base() != t_base_type::TYPE_UUID)) { - indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << endl; + indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << '\n'; } else { - f_const_values_ << indent() << name << " = " << render_const_value(type, value, name) << endl - << endl; + f_const_values_ << indent() << name << " = " << render_const_value(type, value, name) << '\n' + << '\n'; - f_consts_ << indent() << "var " << name << " " << type_to_go_type(type) << endl; + f_consts_ << indent() << "var " << name << " " << type_to_go_type(type) << '\n'; } } @@ -1079,8 +1135,8 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - out << endl << indent() << publicize(v_iter->first->get_string()) << ": " - << render_const_value(field_type, v_iter->second, name, is_optional) << "," << endl; + out << '\n' << indent() << publicize(v_iter->first->get_string()) << ": " + << render_const_value(field_type, v_iter->second, name, is_optional) << "," << '\n'; } indent_down(); @@ -1090,13 +1146,13 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); const map& val = value->get_map(); - out << "map[" << type_to_go_key_type(ktype) << "]" << type_to_go_type(vtype) << "{" << endl; + out << "map[" << type_to_go_key_type(ktype) << "]" << type_to_go_type(vtype) << "{" << '\n'; indent_up(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent() << render_const_value(ktype, v_iter->first, name) << ": " - << render_const_value(vtype, v_iter->second, name) << "," << endl; + << render_const_value(vtype, v_iter->second, name) << "," << '\n'; } indent_down(); @@ -1104,7 +1160,7 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); const vector& val = value->get_list(); - out << "[]" << type_to_go_type(etype) << "{" << endl; + out << "[]" << type_to_go_type(etype) << "{" << '\n'; indent_up(); vector::const_iterator v_iter; @@ -1117,7 +1173,7 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); - out << "[]" << type_to_go_type(etype) << "{" << endl; + out << "[]" << type_to_go_type(etype) << "{" << '\n'; indent_up(); vector::const_iterator v_iter; @@ -1158,12 +1214,12 @@ void t_go_generator::generate_go_struct(t_struct* tstruct, bool is_exception) { generate_go_struct_definition(f_types_, tstruct, is_exception); // generate Validate function std::string tstruct_name(publicize(tstruct->get_name(), false)); - f_types_ << "func (p *" << tstruct_name << ") Validate() error {" << endl; + f_types_ << "func (p *" << tstruct_name << ") Validate() error {" << '\n'; indent_up(); go_validator_generator(this).generate_struct_validator(f_types_, tstruct); - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "return nil" << '\n'; indent_down(); - f_types_ << "}" << endl; + f_types_ << "}" << '\n' << '\n'; } void t_go_generator::get_publicized_name_and_def_value(t_field* tfield, @@ -1179,20 +1235,26 @@ void t_go_generator::generate_go_struct_initializer(ostream& out, t_struct* tstruct, bool is_args_or_result) { out << publicize(type_name(tstruct), is_args_or_result) << "{"; + indent_up(); const vector& members = tstruct->get_members(); + bool empty = true; for (auto member : members) { bool pointer_field = is_pointer_field(member); string publicized_name; t_const_value* def_value; get_publicized_name_and_def_value(member, &publicized_name, &def_value); if (!pointer_field && def_value != nullptr && !omit_initialization(member)) { - out << endl << indent() << publicized_name << ": " - << render_field_initial_value(member, member->get_name(), pointer_field) << "," - << endl; + empty = false; + out << '\n' << indent() << publicized_name << ": " + << render_field_initial_value(member, member->get_name(), pointer_field) << ","; } } - out << "}" << endl; + indent_down(); + if (!empty) { + out << '\n' << indent(); + } + out << "}" << '\n'; } /** @@ -1211,7 +1273,8 @@ void t_go_generator::generate_go_struct_definition(ostream& out, std::string tstruct_name(publicize(tstruct->get_name(), is_args || is_result)); generate_go_docstring(out, tstruct); - out << indent() << "type " << tstruct_name << " struct {" << endl; + generate_deprecation_comment(out, tstruct->annotations_); + out << indent() << "type " << tstruct_name << " struct {" << '\n'; /* Here we generate the structure specification for the fastbinary codec. These specifications have the following structure: @@ -1253,9 +1316,9 @@ void t_go_generator::generate_go_struct_definition(ostream& out, } int last_unused = sorted_keys_pos - 1; if (first_unused < last_unused) { - indent(out) << "// unused fields # " << first_unused << " to " << last_unused << endl; + indent(out) << "// unused fields # " << first_unused << " to " << last_unused << '\n'; } else if (first_unused == last_unused) { - indent(out) << "// unused field # " << first_unused << endl; + indent(out) << "// unused field # " << first_unused << '\n'; } } @@ -1290,31 +1353,34 @@ void t_go_generator::generate_go_struct_definition(ostream& out, // Trailing whitespace gotag.resize(gotag.size()-1); + generate_deprecation_comment(out, (*m_iter)->annotations_); indent(out) << publicize((*m_iter)->get_name()) << " " << goType << " `thrift:\"" << escape_string((*m_iter)->get_name()) << "," << sorted_keys_pos; if ((*m_iter)->get_req() == t_field::T_REQUIRED) { out << ",required"; } - out << "\" " << gotag << "`" << endl; + out << "\" " << gotag << "`" << '\n'; sorted_keys_pos++; } } else { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_deprecation_comment(out, (*m_iter)->annotations_); // This fills in default values, as opposed to nulls out << indent() << publicize((*m_iter)->get_name()) << " " - << type_to_go_type((*m_iter)->get_type()) << endl; + << type_to_go_type((*m_iter)->get_type()) << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; - out << indent() << "func New" << tstruct_name << "() *" << tstruct_name << " {" << endl; + out << indent() << "}" << '\n' << '\n'; + generate_deprecation_comment(out, tstruct->annotations_); + out << indent() << "func New" << tstruct_name << "() *" << tstruct_name << " {" << '\n'; indent_up(); out << indent() << "return &"; generate_go_struct_initializer(out, tstruct, is_result || is_args); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // Default values for optional fields for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string publicized_name; @@ -1324,12 +1390,14 @@ void t_go_generator::generate_go_struct_definition(ostream& out, string goType = type_to_go_type_with_opt(fieldType, false); string def_var_name = tstruct_name + "_" + publicized_name + "_DEFAULT"; if ((*m_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*m_iter)) { + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "var " << def_var_name << " " << goType; if (def_value != nullptr) { out << " = " << render_const_value(fieldType, def_value, (*m_iter)->get_name()); } - out << endl; + out << '\n'; } + out << '\n'; // num_setable is used for deciding if Count* methods will be generated for union fields. // This applies to all nullable fields including slices (used for set, list and binary) and maps, not just pointers. @@ -1341,25 +1409,27 @@ void t_go_generator::generate_go_struct_definition(ostream& out, if (is_pointer_field(*m_iter)) { string goOptType = type_to_go_type_with_opt(fieldType, true); string maybepointer = goOptType != goType ? "*" : ""; + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() " - << goType << " {" << endl; + << goType << " {" << '\n'; indent_up(); - out << indent() << "if !p.IsSet" << publicized_name << "() {" << endl; + out << indent() << "if !p.IsSet" << publicized_name << "() {" << '\n'; indent_up(); - out << indent() << "return " << def_var_name << endl; + out << indent() << "return " << def_var_name << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "return " << maybepointer << "p." << publicized_name << endl; + out << indent() << "}" << '\n'; + out << indent() << "return " << maybepointer << "p." << publicized_name << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n' << '\n'; } else { - out << endl; + out << '\n'; + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() " - << goType << " {" << endl; + << goType << " {" << '\n'; indent_up(); - out << indent() << "return p." << publicized_name << endl; + out << indent() << "return p." << publicized_name << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1374,57 +1444,57 @@ void t_go_generator::generate_go_struct_definition(ostream& out, generate_go_struct_equals(out, tstruct, tstruct_name); } - out << indent() << "func (p *" << tstruct_name << ") String() string {" << endl; + out << indent() << "func (p *" << tstruct_name << ") String() string {" << '\n'; indent_up(); - out << indent() << "if p == nil {" << endl; + out << indent() << "if p == nil {" << '\n'; indent_up(); - out << indent() << "return \"\"" << endl; + out << indent() << "return \"\"" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; out << indent() << "return fmt.Sprintf(\"" << escape_string(tstruct_name) << "(%+v)\", *p)" - << endl; + << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (is_exception) { - out << indent() << "func (p *" << tstruct_name << ") Error() string {" << endl; + out << indent() << "func (p *" << tstruct_name << ") Error() string {" << '\n'; indent_up(); - out << indent() << "return p.String()" << endl; + out << indent() << "return p.String()" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "func (" << tstruct_name << ") TExceptionType() thrift.TExceptionType {" << endl; + out << indent() << "func (" << tstruct_name << ") TExceptionType() thrift.TExceptionType {" << '\n'; indent_up(); - out << indent() << "return thrift.TExceptionTypeCompiled" << endl; + out << indent() << "return thrift.TExceptionTypeCompiled" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; out << indent() << "var _ thrift.TException = (*" << tstruct_name << ")(nil)" - << endl << endl; + << '\n' << '\n'; } if (!read_write_private_) { // Generate the implementation of slog.LogValuer, // see: https://issues.apache.org/jira/browse/THRIFT-5745 - out << indent() << "func (p *" << tstruct_name << ") LogValue() slog.Value {" << endl; + out << indent() << "func (p *" << tstruct_name << ") LogValue() slog.Value {" << '\n'; indent_up(); - out << indent() << "if p == nil {" << endl; + out << indent() << "if p == nil {" << '\n'; indent_up(); - out << indent() << "return slog.AnyValue(nil)" << endl; + out << indent() << "return slog.AnyValue(nil)" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "v := thrift.SlogTStructWrapper{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "v := thrift.SlogTStructWrapper{" << '\n'; indent_up(); - out << indent() << "Type: \"*" << package_name_ << "." << tstruct_name << "\"," << endl; - out << indent() << "Value: p," << endl; + out << indent() << "Type: \"*" << package_name_ << "." << tstruct_name << "\"," << '\n'; + out << indent() << "Value: p," << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "return slog.AnyValue(v)" << endl; + out << indent() << "}" << '\n'; + out << indent() << "return slog.AnyValue(v)" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; out << indent() << "var _ slog.LogValuer = (*" << tstruct_name << ")(nil)" - << endl << endl; + << '\n' << '\n'; } } @@ -1443,26 +1513,27 @@ void t_go_generator::generate_isset_helpers(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); if ((*f_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*f_iter)) { + generate_deprecation_comment(out, (*f_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") IsSet" << field_name << "() bool {" - << endl; + << '\n'; indent_up(); t_type* ttype = (*f_iter)->get_type()->get_true_type(); bool is_byteslice = ttype->is_binary(); bool compare_to_nil_only = ttype->is_set() || ttype->is_list() || ttype->is_map() || (is_byteslice && !(*f_iter)->get_value()); if (is_pointer_field(*f_iter) || compare_to_nil_only) { - out << indent() << "return p." << field_name << " != nil" << endl; + out << indent() << "return p." << field_name << " != nil" << '\n'; } else { string def_var_name = tstruct_name + "_" + field_name + "_DEFAULT"; if (is_byteslice) { out << indent() << "return !bytes.Equal(p." << field_name << ", " << def_var_name << ")" - << endl; + << '\n'; } else { - out << indent() << "return p." << field_name << " != " << def_var_name << endl; + out << indent() << "return p." << field_name << " != " << def_var_name << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } } @@ -1480,9 +1551,9 @@ void t_go_generator::generate_countsetfields_helper(ostream& out, const string escaped_tstruct_name(escape_string(tstruct->get_name())); out << indent() << "func (p *" << tstruct_name << ") CountSetFields" << tstruct_name << "() int {" - << endl; + << '\n'; indent_up(); - out << indent() << "count := 0" << endl; + out << indent() << "count := 0" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) continue; @@ -1494,16 +1565,16 @@ void t_go_generator::generate_countsetfields_helper(ostream& out, const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << "if (p.IsSet" << field_name << "()) {" << endl; + out << indent() << "if (p.IsSet" << field_name << "()) {" << '\n'; indent_up(); - out << indent() << "count++" << endl; + out << indent() << "count++" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << indent() << "return count" << endl << endl; + out << indent() << "return count" << '\n' << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1518,33 +1589,41 @@ void t_go_generator::generate_go_struct_reader(ostream& out, vector::const_iterator f_iter; string escaped_tstruct_name(escape_string(tstruct->get_name())); out << indent() << "func (p *" << tstruct_name << ") " << read_method_name_ << "(ctx context.Context, iprot thrift.TProtocol) error {" - << endl; + << '\n'; indent_up(); - out << indent() << "if _, err := iprot.ReadStructBegin(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T read error: \", p), err)" - << endl; - out << indent() << "}" << endl << endl; + out << indent() << "if _, err := iprot.ReadStructBegin(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T read error: \", p), err)" + << '\n'; + indent_down(); + out << indent() << "}" << '\n' << '\n'; // Required variables does not have IsSet functions, so we need tmp vars to check them. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - indent(out) << "var isset" << field_name << " bool = false;" << endl; + indent(out) << "var isset" << field_name << " bool = false;" << '\n'; } } - out << endl; + out << '\n'; // Loop over reading in fields - indent(out) << "for {" << endl; + indent(out) << "for {" << '\n'; indent_up(); // Read beginning field marker - out << indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T field %d read error: \", p, fieldId), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T field %d read error: \", p, fieldId), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Check for field STOP marker and break - out << indent() << "if fieldTypeId == thrift.STOP { break; }" << endl; + out << indent() << "if fieldTypeId == thrift.STOP {" << '\n'; + indent_up(); + out << indent() << "break" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; string thriftFieldTypeId; // Generate deserialization code for known cases @@ -1553,7 +1632,7 @@ void t_go_generator::generate_go_struct_reader(ostream& out, // Switch statement on the field we are reading, false if no fields present bool have_switch = !fields.empty(); if (have_switch) { - indent(out) << "switch fieldId {" << endl; + indent(out) << "switch fieldId {" << '\n'; } // All the fields we know @@ -1569,7 +1648,7 @@ void t_go_generator::generate_go_struct_reader(ostream& out, field_method_suffix *= -1; } - out << indent() << "case " << field_id << ":" << endl; + out << indent() << "case " << field_id << ":" << '\n'; indent_up(); thriftFieldTypeId = type_to_enum((*f_iter)->get_type()); @@ -1577,23 +1656,31 @@ void t_go_generator::generate_go_struct_reader(ostream& out, thriftFieldTypeId = "thrift.STRING"; } - out << indent() << "if fieldTypeId == " << thriftFieldTypeId << " {" << endl; - out << indent() << " if err := p." << field_method_prefix << field_method_suffix << "(ctx, iprot); err != nil {" - << endl; - out << indent() << " return err" << endl; - out << indent() << " }" << endl; + out << indent() << "if fieldTypeId == " << thriftFieldTypeId << " {" << '\n'; + indent_up(); + out << indent() << "if err := p." << field_method_prefix << field_method_suffix << "(ctx, iprot); err != nil {" + << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Mark required field as read if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << " isset" << field_name << " = true" << endl; + out << indent() << "isset" << field_name << " = true" << '\n'; } - out << indent() << "} else {" << endl; - out << indent() << " if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << " }" << endl; - out << indent() << "}" << endl; + indent_down(); + out << indent() << "} else {" << '\n'; + indent_up(); + out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; indent_down(); @@ -1601,46 +1688,54 @@ void t_go_generator::generate_go_struct_reader(ostream& out, // Begin switch default case if (have_switch) { - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); } // Skip unknown fields in either case - out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // End switch default case if (have_switch) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } // Read field end marker - out << indent() << "if err := iprot.ReadFieldEnd(ctx); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadFieldEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if err := iprot.ReadStructEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T read struct end error: \", p), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if err := iprot.ReadStructEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T read struct end error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Return error if any required fields are missing. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << "if !isset" << field_name << "{" << endl; - out << indent() << " return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " - "fmt.Errorf(\"Required field " << field_name << " is not set\"));" << endl; - out << indent() << "}" << endl; + out << indent() << "if !isset" << field_name << "{" << '\n'; + indent_up(); + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"Required field " << field_name << " is not set\"))" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } - out << indent() << "return nil" << endl; + out << indent() << "return nil" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_type_name(publicize((*f_iter)->get_type()->get_name())); @@ -1654,13 +1749,13 @@ void t_go_generator::generate_go_struct_reader(ostream& out, field_method_suffix *= -1; } - out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix - << "(ctx context.Context, iprot thrift.TProtocol) error {" << endl; + out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix + << "(ctx context.Context, iprot thrift.TProtocol) error {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, false, "p."); + out << indent() << "return nil" << '\n'; indent_down(); - out << indent() << " return nil" << endl; - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1673,18 +1768,23 @@ void t_go_generator::generate_go_struct_writer(ostream& out, string name(tstruct->get_name()); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "func (p *" << tstruct_name << ") " << write_method_name_ << "(ctx context.Context, oprot thrift.TProtocol) error {" << endl; + indent(out) << "func (p *" << tstruct_name << ") " << write_method_name_ << "(ctx context.Context, oprot thrift.TProtocol) error {" << '\n'; indent_up(); if (tstruct->is_union() && uses_countsetfields) { std::string tstruct_name(publicize(tstruct->get_name())); - out << indent() << "if c := p.CountSetFields" << tstruct_name << "(); c != 1 {" << endl - << indent() - << " return fmt.Errorf(\"%T write union: exactly one field must be set (%d set)\", p, c)" - << endl << indent() << "}" << endl; + out << indent() << "if c := p.CountSetFields" << tstruct_name << "(); c != 1 {" << '\n'; + indent_up(); + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"%T write union: exactly one field must be set (%d set)\", p, c))" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } - out << indent() << "if err := oprot.WriteStructBegin(ctx, \"" << name << "\"); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T write struct begin error: \", p), err) }" << endl; + out << indent() << "if err := oprot.WriteStructBegin(ctx, \"" << name << "\"); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T write struct begin error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; string field_name; string escape_field_name; @@ -1692,7 +1792,7 @@ void t_go_generator::generate_go_struct_writer(ostream& out, t_field::e_req field_required; int32_t field_id = -1; - out << indent() << "if p != nil {" << endl; + out << indent() << "if p != nil {" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1708,20 +1808,26 @@ void t_go_generator::generate_go_struct_writer(ostream& out, } out << indent() << "if err := p." << field_method_prefix << field_method_suffix - << "(ctx, oprot); err != nil { return err }" << endl; + << "(ctx, oprot); err != nil { return err }" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; // Write the struct map - out << indent() << "if err := oprot.WriteFieldStop(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"write field stop error: \", err) }" << endl; - out << indent() << "if err := oprot.WriteStructEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"write struct stop error: \", err) }" << endl; - out << indent() << "return nil" << endl; + out << indent() << "if err := oprot.WriteFieldStop(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"write field stop error: \", err)" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n'; + out << indent() << "if err := oprot.WriteStructEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"write struct stop error: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "return nil" << '\n'; + indent_down(); + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_method_prefix("writeField"); @@ -1738,35 +1844,41 @@ void t_go_generator::generate_go_struct_writer(ostream& out, } out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix - << "(ctx context.Context, oprot thrift.TProtocol) (err error) {" << endl; + << "(ctx context.Context, oprot thrift.TProtocol) (err error) {" << '\n'; indent_up(); if (field_required == t_field::T_OPTIONAL) { - out << indent() << "if p.IsSet" << publicize(field_name) << "() {" << endl; + out << indent() << "if p.IsSet" << publicize(field_name) << "() {" << '\n'; indent_up(); } out << indent() << "if err := oprot.WriteFieldBegin(ctx, \"" << escape_field_name << "\", " - << type_to_enum((*f_iter)->get_type()) << ", " << field_id << "); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T write field begin error " - << field_id << ":" << escape_field_name << ": \", p), err) }" << endl; + << type_to_enum((*f_iter)->get_type()) << ", " << field_id << "); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T write field begin error " + << field_id << ":" << escape_field_name << ": \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "p."); // Write field closer - out << indent() << "if err := oprot.WriteFieldEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T write field end error " - << field_id << ":" << escape_field_name << ": \", p), err) }" << endl; + out << indent() << "if err := oprot.WriteFieldEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T write field end error " + << field_id << ":" << escape_field_name << ": \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; if (field_required == t_field::T_OPTIONAL) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << " return err" << endl; - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1777,20 +1889,20 @@ void t_go_generator::generate_go_struct_equals(ostream& out, const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; indent(out) << "func (p *" << tstruct_name << ") " << equals_method_name_ << "(other *" - << tstruct_name << ") bool {" << endl; + << tstruct_name << ") bool {" << '\n'; indent_up(); string field_name; string publicize_field_name; - out << indent() << "if p == other {" << endl; + out << indent() << "if p == other {" << '\n'; indent_up(); - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "} else if p == nil || other == nil {" << endl; + out << indent() << "} else if p == nil || other == nil {" << '\n'; indent_up(); - out << indent() << "return false" << endl; + out << indent() << "return false" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { field_name = (*f_iter)->get_name(); @@ -1806,23 +1918,23 @@ void t_go_generator::generate_go_struct_equals(ostream& out, && (ttype->is_base_type() || ttype->is_enum() || ttype->is_container())) { string tgtv = "(*" + tgt + ")"; string srcv = "(*" + src + ")"; - out << indent() << "if " << tgt << " != " << src << " {" << endl; + out << indent() << "if " << tgt << " != " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << tgt << " == nil || " << src << " == nil {" << endl; + out << indent() << "if " << tgt << " == nil || " << src << " == nil {" << '\n'; indent_up(); - out << indent() << "return false" << endl; + out << indent() << "return false" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; generate_go_equals(out, field_type, tgtv, srcv); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { generate_go_equals(out, field_type, tgt, src); } } - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1842,7 +1954,7 @@ void t_go_generator::generate_service(t_service* tservice) { if(!skip_remote_) { generate_service_remote(tservice); } - f_types_ << endl; + f_types_ << '\n'; } /** @@ -1853,7 +1965,7 @@ void t_go_generator::generate_service(t_service* tservice) { void t_go_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_types_ << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_types_ << "// HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1906,31 +2018,35 @@ void t_go_generator::generate_service_interface(t_service* tservice) { extends = type_name(tservice->get_extends()); size_t index = extends.rfind("."); + indent_up(); if (index != string::npos) { - extends_if = "\n" + indent() + " " + extends.substr(0, index + 1) + extends_if = "\n" + indent() + extends.substr(0, index + 1) + publicize(extends.substr(index + 1)) + "\n"; } else { extends_if = "\n" + indent() + publicize(extends) + "\n"; } + indent_down(); } + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "type " << interfaceName << " interface {" << extends_if; indent_up(); generate_go_docstring(f_types_, tservice); vector functions = tservice->get_functions(); if (!functions.empty()) { - f_types_ << endl; + f_types_ << '\n'; vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_go_docstring(f_types_, (*f_iter)); - f_types_ << indent() << function_signature_if(*f_iter, "", true) << endl; + generate_deprecation_comment(f_types_, (*f_iter)->annotations_); + f_types_ << indent() << function_signature_if(*f_iter, "", true) << '\n'; } } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } /** @@ -1963,23 +2079,25 @@ void t_go_generator::generate_service_client(t_service* tservice) { extends_field = extends_client.substr(extends_client.find(".") + 1); generate_go_docstring(f_types_, tservice); - f_types_ << indent() << "type " << serviceName << "Client struct {" << endl; + generate_deprecation_comment(f_types_, tservice->annotations_); + f_types_ << indent() << "type " << serviceName << "Client struct {" << '\n'; indent_up(); if (!extends_client.empty()) { - f_types_ << indent() << "*" << extends_client << endl; + f_types_ << indent() << "*" << extends_client << '\n'; } else { - f_types_ << indent() << "c thrift.TClient" << endl; - f_types_ << indent() << "meta thrift.ResponseMeta" << endl; + f_types_ << indent() << "c thrift.TClient" << '\n'; + f_types_ << indent() << "meta thrift.ResponseMeta" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Legacy constructor function + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "ClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *" << serviceName - << "Client {" << endl; + << "Client {" << '\n'; indent_up(); f_types_ << indent() << "return &" << serviceName << "Client"; @@ -1987,72 +2105,74 @@ void t_go_generator::generate_service_client(t_service* tservice) { f_types_ << "{" << extends_field << ": " << extends_client_new << "Factory(t, f)}"; } else { indent_up(); - f_types_ << "{" << endl; - f_types_ << indent() << "c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t))," << endl; + f_types_ << "{" << '\n'; + f_types_ << indent() << "c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t))," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Legacy constructor function with custom input & output protocols + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "ClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *" - << serviceName << "Client {" << endl; + << serviceName << "Client {" << '\n'; indent_up(); f_types_ << indent() << "return &" << serviceName << "Client"; if (!extends.empty()) { f_types_ << "{" << extends_field << ": " << extends_client_new << "Protocol(t, iprot, oprot)}" - << endl; + << '\n'; } else { indent_up(); - f_types_ << "{" << endl; - f_types_ << indent() << "c: thrift.NewTStandardClient(iprot, oprot)," << endl; + f_types_ << "{" << '\n'; + f_types_ << indent() << "c: thrift.NewTStandardClient(iprot, oprot)," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Constructor function + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName - << "Client(c thrift.TClient) *" << serviceName << "Client {" << endl; + << "Client(c thrift.TClient) *" << serviceName << "Client {" << '\n'; indent_up(); - f_types_ << indent() << "return &" << serviceName << "Client{" << endl; + f_types_ << indent() << "return &" << serviceName << "Client{" << '\n'; indent_up(); if (!extends.empty()) { - f_types_ << indent() << extends_field << ": " << extends_client_new << "(c)," << endl; + f_types_ << indent() << extends_field << ": " << extends_client_new << "(c)," << '\n'; } else { - f_types_ << indent() << "c: c," << endl; + f_types_ << indent() << "c: c," << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; if (extends.empty()) { - f_types_ << indent() << "func (p *" << serviceName << "Client) Client_() thrift.TClient {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) Client_() thrift.TClient {" << '\n'; indent_up(); - f_types_ << indent() << "return p.c" << endl; + f_types_ << indent() << "return p.c" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; - f_types_ << indent() << "func (p *" << serviceName << "Client) LastResponseMeta_() thrift.ResponseMeta {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) LastResponseMeta_() thrift.ResponseMeta {" << '\n'; indent_up(); - f_types_ << indent() << "return p.meta" << endl; + f_types_ << indent() << "return p.meta" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; - f_types_ << indent() << "func (p *" << serviceName << "Client) SetLastResponseMeta_(meta thrift.ResponseMeta) {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) SetLastResponseMeta_(meta thrift.ResponseMeta) {" << '\n'; indent_up(); - f_types_ << indent() << "p.meta = meta" << endl; + f_types_ << indent() << "p.meta = meta" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } // Generate client method implementations @@ -2066,60 +2186,61 @@ void t_go_generator::generate_service_client(t_service* tservice) { string funname = publicize((*f_iter)->get_name()); // Open function generate_go_docstring(f_types_, (*f_iter)); + generate_deprecation_comment(f_types_, (*f_iter)->annotations_); f_types_ << indent() << "func (p *" << serviceName << "Client) " - << function_signature_if(*f_iter, "", true) << " {" << endl; + << function_signature_if(*f_iter, "", true) << " {" << '\n'; indent_up(); std::string method = (*f_iter)->get_name(); std::string argsType = publicize(method + "_args", true); std::string argsName = tmp("_args"); - f_types_ << indent() << "var " << argsName << " " << argsType << endl; + f_types_ << indent() << "var " << argsName << " " << argsType << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_types_ << indent() << argsName << "." << publicize((*fld_iter)->get_name()) - << " = " << variable_name_to_go_name((*fld_iter)->get_name()) << endl; + << " = " << variable_name_to_go_name((*fld_iter)->get_name()) << '\n'; } if (!(*f_iter)->is_oneway()) { std::string metaName = tmp("_meta"); std::string resultName = tmp("_result"); std::string resultType = publicize(method + "_result", true); - f_types_ << indent() << "var " << resultName << " " << resultType << endl; - f_types_ << indent() << "var " << metaName << " thrift.ResponseMeta" << endl; + f_types_ << indent() << "var " << resultName << " " << resultType << '\n'; + f_types_ << indent() << "var " << metaName << " thrift.ResponseMeta" << '\n'; f_types_ << indent() << metaName << ", _err = p.Client_().Call(ctx, \"" - << method << "\", &" << argsName << ", &" << resultName << ")" << endl; - f_types_ << indent() << "p.SetLastResponseMeta_(" << metaName << ")" << endl; - f_types_ << indent() << "if _err != nil {" << endl; + << method << "\", &" << argsName << ", &" << resultName << ")" << '\n'; + f_types_ << indent() << "p.SetLastResponseMeta_(" << metaName << ")" << '\n'; + f_types_ << indent() << "if _err != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; if (!xceptions.empty()) { - f_types_ << indent() << "switch {" << endl; + f_types_ << indent() << "switch {" << '\n'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const std::string pubname = publicize((*x_iter)->get_name()); const std::string field = resultName + "." + pubname; - f_types_ << indent() << "case " << field << "!= nil:" << endl; + f_types_ << indent() << "case " << field << "!= nil:" << '\n'; indent_up(); if (!(*f_iter)->get_returntype()->is_void()) { - f_types_ << indent() << "return _r, " << field << endl; + f_types_ << indent() << "return _r, " << field << '\n'; } else { - f_types_ << indent() << "return "<< field << endl; + f_types_ << indent() << "return "<< field << '\n'; } indent_down(); } - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } if ((*f_iter)->get_returntype()->is_struct()) { @@ -2130,37 +2251,37 @@ void t_go_generator::generate_service_client(t_service* tservice) { // struct in go. std::string retName = tmp("_ret"); f_types_ << indent() << "if " << retName << " := " << resultName - << ".GetSuccess(); " << retName << " != nil {" << endl; + << ".GetSuccess(); " << retName << " != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return " << retName << ", nil" << endl; + f_types_ << indent() << "return " << retName << ", nil" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "return nil, " << "thrift.NewTApplicationException(thrift.MISSING_RESULT, \"" - << method << " failed: unknown result\")" << endl; + << method << " failed: unknown result\")" << '\n'; } else if (!(*f_iter)->get_returntype()->is_void()) { - f_types_ << indent() << "return " << resultName << ".GetSuccess(), nil" << endl; + f_types_ << indent() << "return " << resultName << ".GetSuccess(), nil" << '\n'; } else { - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "return nil" << '\n'; } } else { // Since we don't have response meta for oneway calls, overwrite it with // an empty one to avoid users getting the meta from last call and // mistaken it as from the oneway call. - f_types_ << indent() << "p.SetLastResponseMeta_(thrift.ResponseMeta{})" << endl; + f_types_ << indent() << "p.SetLastResponseMeta_(thrift.ResponseMeta{})" << '\n'; // TODO: would be nice to not to duplicate the call generation f_types_ << indent() << "if _, err := p.Client_().Call(ctx, \"" - << method << "\", &" << argsName << ", nil); err != nil {" << endl; + << method << "\", &" << argsName << ", nil); err != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return err" << endl; + f_types_ << indent() << "return err" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "return nil" << '\n'; } indent_down(); - f_types_ << "}" << endl << endl; + f_types_ << "}" << '\n' << '\n'; } } @@ -2223,26 +2344,27 @@ void t_go_generator::generate_service_remote(t_service* tservice) { system_packages.push_back("thrift \"" + gen_thrift_import_ + "\""); f_remote << go_autogen_comment(); - f_remote << indent() << "package main" << endl << endl; - f_remote << indent() << "import (" << endl; + f_remote << indent() << "package main" << '\n' << '\n'; + f_remote << indent() << "import (" << '\n'; f_remote << render_system_packages(system_packages); f_remote << indent() << render_included_programs(unused_protection); f_remote << render_program_import(program_, unused_protection); - f_remote << indent() << ")" << endl; - f_remote << indent() << endl; + f_remote << indent() << ")" << '\n'; + f_remote << indent() << '\n'; f_remote << indent() << unused_protection; // filled in render_included_programs() - f_remote << indent() << endl; - f_remote << indent() << "func Usage() {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Usage of \", os.Args[0], \" " + f_remote << indent() << '\n'; + f_remote << indent() << "func Usage() {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Usage of \", os.Args[0], \" " "[-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]:\")" - << endl; - f_remote << indent() << " flag.PrintDefaults()" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"\\nFunctions:\")" << endl; + << '\n'; + f_remote << indent() << "flag.PrintDefaults()" << '\n'; + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"\\nFunctions:\")" << '\n'; string package_name_aliased = package_identifiers_[get_real_go_module(program_)]; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_remote << " fmt.Fprintln(os.Stderr, \" " << (*f_iter)->get_returntype()->get_name() << " " + f_remote << indent() << "fmt.Fprintln(os.Stderr, \" " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "("; t_struct* arg_struct = (*f_iter)->get_arglist(); const std::vector& args = arg_struct->get_members(); @@ -2259,143 +2381,184 @@ void t_go_generator::generate_service_remote(t_service* tservice) { f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name(); } - f_remote << ")\")" << endl; + f_remote << ")\")" << '\n'; } - f_remote << indent() << " fmt.Fprintln(os.Stderr)" << endl; - f_remote << indent() << " os.Exit(0)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - - f_remote << indent() << "type httpHeaders map[string]string" << endl; - f_remote << indent() << endl; - f_remote << indent() << "func (h httpHeaders) String() string {" << endl; - f_remote << indent() << " var m map[string]string = h" << endl; - f_remote << indent() << " return fmt.Sprintf(\"%s\", m)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "func (h httpHeaders) Set(value string) error {" << endl; - f_remote << indent() << " parts := strings.Split(value, \": \")" << endl; - f_remote << indent() << " if len(parts) != 2 {" << endl; - f_remote << indent() << " return fmt.Errorf(\"header should be of format 'Key: Value'\")" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " h[parts[0]] = parts[1]" << endl; - f_remote << indent() << " return nil" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - - f_remote << indent() << "func main() {" << endl; + f_remote << indent() << "fmt.Fprintln(os.Stderr)" << '\n'; + f_remote << indent() << "os.Exit(0)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + + f_remote << indent() << "type httpHeaders map[string]string" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "func (h httpHeaders) String() string {" << '\n'; + indent_up(); + f_remote << indent() << "var m map[string]string = h" << '\n'; + f_remote << indent() << "return fmt.Sprintf(\"%s\", m)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "func (h httpHeaders) Set(value string) error {" << '\n'; + indent_up(); + f_remote << indent() << "parts := strings.Split(value, \": \")" << '\n'; + f_remote << indent() << "if len(parts) != 2 {" << '\n'; + indent_up(); + f_remote << indent() << "return fmt.Errorf(\"header should be of format 'Key: Value'\")" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "h[parts[0]] = parts[1]" << '\n'; + f_remote << indent() << "return nil" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + + f_remote << indent() << "func main() {" << '\n'; indent_up(); - f_remote << indent() << "flag.Usage = Usage" << endl; - f_remote << indent() << "var host string" << endl; - f_remote << indent() << "var port int" << endl; - f_remote << indent() << "var protocol string" << endl; - f_remote << indent() << "var urlString string" << endl; - f_remote << indent() << "var framed bool" << endl; - f_remote << indent() << "var useHttp bool" << endl; - f_remote << indent() << "headers := make(httpHeaders)" << endl; - f_remote << indent() << "var parsedUrl *url.URL" << endl; - f_remote << indent() << "var trans thrift.TTransport" << endl; - f_remote << indent() << "_ = strconv.Atoi" << endl; - f_remote << indent() << "_ = math.Abs" << endl; - f_remote << indent() << "flag.Usage = Usage" << endl; + f_remote << indent() << "flag.Usage = Usage" << '\n'; + f_remote << indent() << "var host string" << '\n'; + f_remote << indent() << "var port int" << '\n'; + f_remote << indent() << "var protocol string" << '\n'; + f_remote << indent() << "var urlString string" << '\n'; + f_remote << indent() << "var framed bool" << '\n'; + f_remote << indent() << "var useHttp bool" << '\n'; + f_remote << indent() << "headers := make(httpHeaders)" << '\n'; + f_remote << indent() << "var parsedUrl *url.URL" << '\n'; + f_remote << indent() << "var trans thrift.TTransport" << '\n'; + f_remote << indent() << "_ = strconv.Atoi" << '\n'; + f_remote << indent() << "_ = math.Abs" << '\n'; + f_remote << indent() << "flag.Usage = Usage" << '\n'; f_remote << indent() << "flag.StringVar(&host, \"h\", \"localhost\", \"Specify host and port\")" - << endl; - f_remote << indent() << "flag.IntVar(&port, \"p\", 9090, \"Specify port\")" << endl; + << '\n'; + f_remote << indent() << "flag.IntVar(&port, \"p\", 9090, \"Specify port\")" << '\n'; f_remote << indent() << "flag.StringVar(&protocol, \"P\", \"binary\", \"" - "Specify the protocol (binary, compact, simplejson, json)\")" << endl; - f_remote << indent() << "flag.StringVar(&urlString, \"u\", \"\", \"Specify the url\")" << endl; + "Specify the protocol (binary, compact, simplejson, json)\")" << '\n'; + f_remote << indent() << "flag.StringVar(&urlString, \"u\", \"\", \"Specify the url\")" << '\n'; f_remote << indent() << "flag.BoolVar(&framed, \"framed\", false, \"Use framed transport\")" - << endl; - f_remote << indent() << "flag.BoolVar(&useHttp, \"http\", false, \"Use http\")" << endl; - f_remote << indent() << "flag.Var(headers, \"H\", \"Headers to set on the http(s) request (e.g. -H \\\"Key: Value\\\")\")" << endl; - f_remote << indent() << "flag.Parse()" << endl; - f_remote << indent() << endl; - f_remote << indent() << "if len(urlString) > 0 {" << endl; - f_remote << indent() << " var err error" << endl; - f_remote << indent() << " parsedUrl, err = url.Parse(urlString)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " host = parsedUrl.Host" << endl; - f_remote << indent() << " useHttp = len(parsedUrl.Scheme) <= 0 || parsedUrl.Scheme == \"http\" || parsedUrl.Scheme == \"https\"" - << endl; - f_remote << indent() << "} else if useHttp {" << endl; - f_remote << indent() << " _, err := url.Parse(fmt.Sprint(\"http://\", host, \":\", port))" - << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "cmd := flag.Arg(0)" << endl; - f_remote << indent() << "var err error" << endl; - f_remote << indent() << "var cfg *thrift.TConfiguration = nil" << endl; - f_remote << indent() << "if useHttp {" << endl; - f_remote << indent() << " trans, err = thrift.NewTHttpClient(parsedUrl.String())" << endl; - f_remote << indent() << " if len(headers) > 0 {" << endl; - f_remote << indent() << " httptrans := trans.(*thrift.THttpClient)" << endl; - f_remote << indent() << " for key, value := range headers {" << endl; - f_remote << indent() << " httptrans.SetHeader(key, value)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "} else {" << endl; - f_remote << indent() << " portStr := fmt.Sprint(port)" << endl; - f_remote << indent() << " if strings.Contains(host, \":\") {" << endl; - f_remote << indent() << " host, portStr, err = net.SplitHostPort(host)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"error with host:\", err)" - << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " trans = thrift.NewTSocketConf(net.JoinHostPort(host, portStr), cfg)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"error resolving address:\", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " if framed {" << endl; - f_remote << indent() << " trans = thrift.NewTFramedTransportConf(trans, cfg)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error creating transport\", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "defer trans.Close()" << endl; - f_remote << indent() << "var protocolFactory thrift.TProtocolFactory" << endl; - f_remote << indent() << "switch protocol {" << endl; - f_remote << indent() << "case \"compact\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"simplejson\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"json\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTJSONProtocolFactory()" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"binary\", \"\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTBinaryProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "default:" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Invalid protocol specified: \", protocol)" - << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "iprot := protocolFactory.GetProtocol(trans)" << endl; - f_remote << indent() << "oprot := protocolFactory.GetProtocol(trans)" << endl; + << '\n'; + f_remote << indent() << "flag.BoolVar(&useHttp, \"http\", false, \"Use http\")" << '\n'; + f_remote << indent() << "flag.Var(headers, \"H\", \"Headers to set on the http(s) request (e.g. -H \\\"Key: Value\\\")\")" << '\n'; + f_remote << indent() << "flag.Parse()" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "if len(urlString) > 0 {" << '\n'; + indent_up(); + f_remote << indent() << "var err error" << '\n'; + f_remote << indent() << "parsedUrl, err = url.Parse(urlString)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "host = parsedUrl.Host" << '\n'; + f_remote << indent() << "useHttp = len(parsedUrl.Scheme) <= 0 || parsedUrl.Scheme == \"http\" || parsedUrl.Scheme == \"https\"" + << '\n'; + indent_down(); + f_remote << indent() << "} else if useHttp {" << '\n'; + indent_up(); + f_remote << indent() << "_, err := url.Parse(fmt.Sprint(\"http://\", host, \":\", port))" + << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "cmd := flag.Arg(0)" << '\n'; + f_remote << indent() << "var err error" << '\n'; + f_remote << indent() << "var cfg *thrift.TConfiguration = nil" << '\n'; + f_remote << indent() << "if useHttp {" << '\n'; + indent_up(); + f_remote << indent() << "trans, err = thrift.NewTHttpClient(parsedUrl.String())" << '\n'; + f_remote << indent() << "if len(headers) > 0 {" << '\n'; + indent_up(); + f_remote << indent() << "httptrans := trans.(*thrift.THttpClient)" << '\n'; + f_remote << indent() << "for key, value := range headers {" << '\n'; + indent_up(); + f_remote << indent() << "httptrans.SetHeader(key, value)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "} else {" << '\n'; + indent_up(); + f_remote << indent() << "portStr := fmt.Sprint(port)" << '\n'; + f_remote << indent() << "if strings.Contains(host, \":\") {" << '\n'; + indent_up(); + f_remote << indent() << "host, portStr, err = net.SplitHostPort(host)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"error with host:\", err)" + << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "trans = thrift.NewTSocketConf(net.JoinHostPort(host, portStr), cfg)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"error resolving address:\", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "if framed {" << '\n'; + indent_up(); + f_remote << indent() << "trans = thrift.NewTFramedTransportConf(trans, cfg)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error creating transport\", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "defer trans.Close()" << '\n'; + f_remote << indent() << "var protocolFactory thrift.TProtocolFactory" << '\n'; + f_remote << indent() << "switch protocol {" << '\n'; + f_remote << indent() << "case \"compact\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "case \"simplejson\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "case \"json\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTJSONProtocolFactory()" << '\n'; + indent_down(); + f_remote << indent() << "case \"binary\", \"\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTBinaryProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "default:" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Invalid protocol specified: \", protocol)" + << '\n'; + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "iprot := protocolFactory.GetProtocol(trans)" << '\n'; + f_remote << indent() << "oprot := protocolFactory.GetProtocol(trans)" << '\n'; f_remote << indent() << "client := " << package_name_aliased << ".New" << publicize(service_name_) - << "Client(thrift.NewTStandardClient(iprot, oprot))" << endl; - f_remote << indent() << "if err := trans.Open(); err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error opening socket to \", " - "host, \":\", port, \" \", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "switch cmd {" << endl; + << "Client(thrift.NewTStandardClient(iprot, oprot))" << '\n'; + f_remote << indent() << "if err := trans.Open(); err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error opening socket to \", " + "host, \":\", port, \" \", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "switch cmd {" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* arg_struct = (*f_iter)->get_arglist(); @@ -2404,13 +2567,15 @@ void t_go_generator::generate_service_remote(t_service* tservice) { string funcName((*f_iter)->get_name()); string pubName(publicize(funcName)); string argumentsName(publicize(funcName + "_args", true, func_to_service[funcName])); - f_remote << indent() << "case \"" << escape_string(funcName) << "\":" << endl; + f_remote << indent() << "case \"" << escape_string(funcName) << "\":" << '\n'; + indent_up(); + f_remote << indent() << "if flag.NArg() - 1 != " << num_args << " {" << '\n'; indent_up(); - f_remote << indent() << "if flag.NArg() - 1 != " << num_args << " {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"" << escape_string(pubName) << " requires " - << num_args << " args\")" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << "}" << endl; + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"" << escape_string(pubName) << " requires " + << num_args << " args\")" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; for (std::vector::size_type i = 0; i < num_args; ++i) { std::vector::size_type flagArg = i + 1; @@ -2419,13 +2584,15 @@ void t_go_generator::generate_service_remote(t_service* tservice) { if (the_type2->is_enum()) { f_remote << indent() << "tmp" << i << ", err := (strconv.Atoi(flag.Arg(" << flagArg << ")))" - << endl; - f_remote << indent() << "if err != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; f_remote << indent() << "argvalue" << i << " := " << package_name_aliased << "." - << publicize(the_type->get_name()) << "(tmp" << i << ")" << endl; + << publicize(the_type->get_name()) << "(tmp" << i << ")" << '\n'; } else if (the_type2->is_base_type()) { t_base_type::t_base e = ((t_base_type*)the_type2)->get_base(); string err(tmp("err")); @@ -2437,72 +2604,84 @@ void t_go_generator::generate_service_remote(t_service* tservice) { case t_base_type::TYPE_STRING: if (the_type2->is_binary()) { f_remote << indent() << "argvalue" << i << " := []byte(flag.Arg(" << flagArg << "))" - << endl; + << '\n'; } else { - f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ")" << '\n'; } break; case t_base_type::TYPE_BOOL: f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ") == \"true\"" - << endl; + << '\n'; break; case t_base_type::TYPE_I8: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int8(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int8(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I16: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int16(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int16(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I32: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int32(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int32(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I64: f_remote << indent() << "argvalue" << i << ", " << err - << " := (strconv.ParseInt(flag.Arg(" << flagArg << "), 10, 64))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (strconv.ParseInt(flag.Arg(" << flagArg << "), 10, 64))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; case t_base_type::TYPE_DOUBLE: f_remote << indent() << "argvalue" << i << ", " << err - << " := (strconv.ParseFloat(flag.Arg(" << flagArg << "), 64))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (strconv.ParseFloat(flag.Arg(" << flagArg << "), 64))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; case t_base_type::TYPE_UUID: f_remote << indent() << "argvalue" << i << ", " << err - << " := (thrift.ParseTuuid(flag.Arg(" << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (thrift.ParseTuuid(flag.Arg(" << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; default: @@ -2524,26 +2703,30 @@ void t_go_generator::generate_service_remote(t_service* tservice) { tstruct_module = package_name_aliased; } - f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << '\n'; f_remote << indent() << mbTrans << " := thrift.NewTMemoryBufferLen(len(" << arg << "))" - << endl; - f_remote << indent() << "defer " << mbTrans << ".Close()" << endl; + << '\n'; + f_remote << indent() << "defer " << mbTrans << ".Close()" << '\n'; f_remote << indent() << "_, " << err1 << " := " << mbTrans << ".WriteString(" << arg << ")" - << endl; - f_remote << indent() << "if " << err1 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << endl; + << '\n'; + f_remote << indent() << "if " << err1 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << '\n'; f_remote << indent() << jsProt << " := " << factory << ".GetProtocol(" << mbTrans << ")" - << endl; + << '\n'; f_remote << indent() << "argvalue" << i << " := " << tstruct_module << ".New" << tstruct_name - << "()" << endl; - f_remote << indent() << err2 << " := argvalue" << i << "." << read_method_name_ << "(context.Background(), " << jsProt << ")" << endl; - f_remote << indent() << "if " << err2 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << "()" << '\n'; + f_remote << indent() << err2 << " := argvalue" << i << "." << read_method_name_ << "(context.Background(), " << jsProt << ")" << '\n'; + f_remote << indent() << "if " << err2 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; } else if (the_type2->is_container() || the_type2->is_xception()) { string arg(tmp("arg")); string mbTrans(tmp("mbTrans")); @@ -2552,29 +2735,33 @@ void t_go_generator::generate_service_remote(t_service* tservice) { string jsProt(tmp("jsProt")); string err2(tmp("err")); std::string argName(publicize(args[i]->get_name())); - f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << '\n'; f_remote << indent() << mbTrans << " := thrift.NewTMemoryBufferLen(len(" << arg << "))" - << endl; - f_remote << indent() << "defer " << mbTrans << ".Close()" << endl; + << '\n'; + f_remote << indent() << "defer " << mbTrans << ".Close()" << '\n'; f_remote << indent() << "_, " << err1 << " := " << mbTrans << ".WriteString(" << arg << ")" - << endl; - f_remote << indent() << "if " << err1 << " != nil { " << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << endl; + << '\n'; + f_remote << indent() << "if " << err1 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << '\n'; f_remote << indent() << jsProt << " := " << factory << ".GetProtocol(" << mbTrans << ")" - << endl; + << '\n'; f_remote << indent() << "containerStruct" << i << " := " << package_name_aliased << ".New" - << argumentsName << "()" << endl; + << argumentsName << "()" << '\n'; f_remote << indent() << err2 << " := containerStruct" << i << ".ReadField" << (i + 1) << "(context.Background(), " - << jsProt << ")" << endl; - f_remote << indent() << "if " << err2 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << jsProt << ")" << '\n'; + f_remote << indent() << "if " << err2 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; f_remote << indent() << "argvalue" << i << " := containerStruct" << i << "." << argName - << endl; + << '\n'; } else { throw("Invalid argument type in generate_service_remote"); } @@ -2585,9 +2772,9 @@ void t_go_generator::generate_service_remote(t_service* tservice) { typedef_module = package_name_aliased; } f_remote << indent() << "value" << i << " := " << typedef_module << "." - << publicize(the_type->get_name()) << "(argvalue" << i << ")" << endl; + << publicize(the_type->get_name()) << "(argvalue" << i << ")" << '\n'; } else { - f_remote << indent() << "value" << i << " := argvalue" << i << endl; + f_remote << indent() << "value" << i << " := argvalue" << i << '\n'; } } @@ -2634,20 +2821,23 @@ void t_go_generator::generate_service_remote(t_service* tservice) { } } - f_remote << "))" << endl; - f_remote << indent() << "fmt.Print(\"\\n\")" << endl; - f_remote << indent() << "break" << endl; + f_remote << "))" << '\n'; + f_remote << indent() << "fmt.Print(\"\\n\")" << '\n'; + f_remote << indent() << "break" << '\n'; indent_down(); } - f_remote << indent() << "case \"\":" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "default:" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Invalid function \", cmd)" << endl; - f_remote << indent() << "}" << endl; + f_remote << indent() << "case \"\":" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + indent_down(); + f_remote << indent() << "default:" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Invalid function \", cmd)" << '\n'; indent_down(); - f_remote << indent() << "}" << endl; + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; // Close service file f_remote.close(); format_go_output(f_remote_name); @@ -2696,80 +2886,99 @@ void t_go_generator::generate_service_server(t_service* tservice) { string self(tmp("self")); if (extends_processor.empty()) { - f_types_ << indent() << "type " << serviceName << "Processor struct {" << endl; - f_types_ << indent() << " processorMap map[string]thrift.TProcessorFunction" << endl; - f_types_ << indent() << " handler " << serviceName << endl; - f_types_ << indent() << "}" << endl << endl; + generate_deprecation_comment(f_types_, tservice->annotations_); + f_types_ << indent() << "type " << serviceName << "Processor struct {" << '\n'; + indent_up(); + f_types_ << indent() << "processorMap map[string]thrift.TProcessorFunction" << '\n'; + f_types_ << indent() << "handler " << serviceName << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) {" - << endl; - f_types_ << indent() << " p.processorMap[key] = processor" << endl; - f_types_ << indent() << "}" << endl << endl; + << '\n'; + indent_up(); + f_types_ << indent() << "p.processorMap[key] = processor" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) GetProcessorFunction(key string) " - "(processor thrift.TProcessorFunction, ok bool) {" << endl; - f_types_ << indent() << " processor, ok = p.processorMap[key]" << endl; - f_types_ << indent() << " return processor, ok" << endl; - f_types_ << indent() << "}" << endl << endl; + "(processor thrift.TProcessorFunction, ok bool) {" << '\n'; + indent_up(); + f_types_ << indent() << "processor, ok = p.processorMap[key]" << '\n'; + f_types_ << indent() << "return processor, ok" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName - << "Processor) ProcessorMap() map[string]thrift.TProcessorFunction {" << endl; - f_types_ << indent() << " return p.processorMap" << endl; - f_types_ << indent() << "}" << endl << endl; + << "Processor) ProcessorMap() map[string]thrift.TProcessorFunction {" << '\n'; + indent_up(); + f_types_ << indent() << "return p.processorMap" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "Processor(handler " << serviceName - << ") *" << serviceName << "Processor {" << endl << endl; + << ") *" << serviceName << "Processor {" << '\n' << '\n'; + indent_up(); f_types_ - << indent() << " " << self << " := &" << serviceName + << indent() << self << " := &" << serviceName << "Processor{handler:handler, processorMap:make(map[string]thrift.TProcessorFunction)}" - << endl; + << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string escapedFuncName(escape_string((*f_iter)->get_name())); - f_types_ << indent() << " " << self << ".processorMap[\"" << escapedFuncName << "\"] = &" + f_types_ << indent() << self << ".processorMap[\"" << escapedFuncName << "\"] = &" << pServiceName << "Processor" << publicize((*f_iter)->get_name()) - << "{handler:handler}" << endl; + << "{handler:handler}" << '\n'; } string x(tmp("x")); - f_types_ << indent() << "return " << self << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "return " << self << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err " - "thrift.TException) {" << endl; - f_types_ << indent() << " name, _, seqId, err2 := iprot.ReadMessageBegin(ctx)" << endl; - f_types_ << indent() << " if err2 != nil { return false, thrift.WrapTException(err2) }" << endl; - f_types_ << indent() << " if processor, ok := p.GetProcessorFunction(name); ok {" << endl; - f_types_ << indent() << " return processor.Process(ctx, seqId, iprot, oprot)" << endl; - f_types_ << indent() << " }" << endl; - f_types_ << indent() << " iprot.Skip(ctx, thrift.STRUCT)" << endl; - f_types_ << indent() << " iprot.ReadMessageEnd(ctx)" << endl; - f_types_ << indent() << " " << x + "thrift.TException) {" << '\n'; + indent_up(); + f_types_ << indent() << "name, _, seqId, err2 := iprot.ReadMessageBegin(ctx)" << '\n'; + f_types_ << indent() << "if err2 != nil { return false, thrift.WrapTException(err2) }" << '\n'; + f_types_ << indent() << "if processor, ok := p.GetProcessorFunction(name); ok {" << '\n'; + indent_up(); + f_types_ << indent() << "return processor.Process(ctx, seqId, iprot, oprot)" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "iprot.Skip(ctx, thrift.STRUCT)" << '\n'; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "" << x << " := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, \"Unknown function " - "\" + name)" << endl; - f_types_ << indent() << " oprot.WriteMessageBegin(ctx, name, thrift.EXCEPTION, seqId)" << endl; - f_types_ << indent() << " " << x << ".Write(ctx, oprot)" << endl; - f_types_ << indent() << " oprot.WriteMessageEnd(ctx)" << endl; - f_types_ << indent() << " oprot.Flush(ctx)" << endl; - f_types_ << indent() << " return false, " << x << endl; - f_types_ << indent() << "" << endl; - f_types_ << indent() << "}" << endl << endl; + "\" + name)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageBegin(ctx, name, thrift.EXCEPTION, seqId)" << '\n'; + f_types_ << indent() << "" << x << ".Write(ctx, oprot)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "oprot.Flush(ctx)" << '\n'; + f_types_ << indent() << "return false, " << x << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; } else { - f_types_ << indent() << "type " << serviceName << "Processor struct {" << endl; - f_types_ << indent() << " *" << extends_processor << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "type " << serviceName << "Processor struct {" << '\n'; + indent_up(); + f_types_ << indent() << "*" << extends_processor << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func New" << serviceName << "Processor(handler " << serviceName - << ") *" << serviceName << "Processor {" << endl; - f_types_ << indent() << " " << self << " := &" << serviceName << "Processor{" - << extends_processor_new << "(handler)}" << endl; + << ") *" << serviceName << "Processor {" << '\n'; + indent_up(); + f_types_ << indent() << self << " := &" << serviceName << "Processor{" + << extends_processor_new << "(handler)}" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string escapedFuncName(escape_string((*f_iter)->get_name())); - f_types_ << indent() << " " << self << ".AddToProcessorMap(\"" << escapedFuncName + f_types_ << indent() << self << ".AddToProcessorMap(\"" << escapedFuncName << "\", &" << pServiceName << "Processor" << publicize((*f_iter)->get_name()) - << "{handler:handler})" << endl; + << "{handler:handler})" << '\n'; } - f_types_ << indent() << " return " << self << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "return " << self << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; } // Generate the process subfunctions @@ -2777,7 +2986,7 @@ void t_go_generator::generate_service_server(t_service* tservice) { generate_process_function(tservice, *f_iter); } - f_types_ << endl; + f_types_ << '\n'; } /** @@ -2794,90 +3003,92 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* // t_struct* xs = tfunction->get_xceptions(); // const std::vector& xceptions = xs->get_members(); - f_types_ << indent() << "type " << processorName << " struct {" << endl; - f_types_ << indent() << " handler " << publicize(tservice->get_name()) << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "type " << processorName << " struct {" << '\n'; + indent_up(); + f_types_ << indent() << "handler " << publicize(tservice->get_name()) << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << processorName << ") Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err " - "thrift.TException) {" << endl; + "thrift.TException) {" << '\n'; indent_up(); string write_err; if (!tfunction->is_oneway()) { write_err = tmp("_write_err"); - f_types_ << indent() << "var " << write_err << " error" << endl; + f_types_ << indent() << "var " << write_err << " thrift.TException" << '\n'; } - f_types_ << indent() << "args := " << argsname << "{}" << endl; - f_types_ << indent() << "if err2 := args." << read_method_name_ << "(ctx, iprot); err2 != nil {" << endl; + f_types_ << indent() << "args := " << argsname << "{}" << '\n'; + f_types_ << indent() << "if err2 := args." << read_method_name_ << "(ctx, iprot); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << endl; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n'; if (!tfunction->is_oneway()) { f_types_ << indent() << "x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err2.Error())" - << endl; + << '\n'; f_types_ << indent() << "oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) - << "\", thrift.EXCEPTION, seqId)" << endl; - f_types_ << indent() << "x.Write(ctx, oprot)" << endl; - f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << endl; - f_types_ << indent() << "oprot.Flush(ctx)" << endl; + << "\", thrift.EXCEPTION, seqId)" << '\n'; + f_types_ << indent() << "x.Write(ctx, oprot)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "oprot.Flush(ctx)" << '\n'; } - f_types_ << indent() << "return false, thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "return false, thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << endl << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n' << '\n'; // Even though we never create the goroutine in oneway handlers, // always have (nop) tickerCancel defined makes the writing part of code // generating easier and less error-prone. - f_types_ << indent() << "tickerCancel := func() {}" << endl; + f_types_ << indent() << "tickerCancel := func() {}" << '\n'; // Only create the goroutine for non-oneways. if (!tfunction->is_oneway()) { - f_types_ << indent() << "// Start a goroutine to do server side connectivity check." << endl; - f_types_ << indent() << "if thrift.ServerConnectivityCheckInterval > 0 {" << endl; + f_types_ << indent() << "// Start a goroutine to do server side connectivity check." << '\n'; + f_types_ << indent() << "if thrift.ServerConnectivityCheckInterval > 0 {" << '\n'; indent_up(); - f_types_ << indent() << "var cancel context.CancelCauseFunc" << endl; - f_types_ << indent() << "ctx, cancel = context.WithCancelCause(ctx)" << endl; - f_types_ << indent() << "defer cancel(nil)" << endl; - f_types_ << indent() << "var tickerCtx context.Context" << endl; - f_types_ << indent() << "tickerCtx, tickerCancel = context.WithCancel(context.Background())" << endl; - f_types_ << indent() << "defer tickerCancel()" << endl; - f_types_ << indent() << "go func(ctx context.Context, cancel context.CancelCauseFunc) {" << endl; + f_types_ << indent() << "var cancel context.CancelCauseFunc" << '\n'; + f_types_ << indent() << "ctx, cancel = context.WithCancelCause(ctx)" << '\n'; + f_types_ << indent() << "defer cancel(nil)" << '\n'; + f_types_ << indent() << "var tickerCtx context.Context" << '\n'; + f_types_ << indent() << "tickerCtx, tickerCancel = context.WithCancel(context.Background())" << '\n'; + f_types_ << indent() << "defer tickerCancel()" << '\n'; + f_types_ << indent() << "go func(ctx context.Context, cancel context.CancelCauseFunc) {" << '\n'; indent_up(); - f_types_ << indent() << "ticker := time.NewTicker(thrift.ServerConnectivityCheckInterval)" << endl; - f_types_ << indent() << "defer ticker.Stop()" << endl; - f_types_ << indent() << "for {" << endl; + f_types_ << indent() << "ticker := time.NewTicker(thrift.ServerConnectivityCheckInterval)" << '\n'; + f_types_ << indent() << "defer ticker.Stop()" << '\n'; + f_types_ << indent() << "for {" << '\n'; indent_up(); - f_types_ << indent() << "select {" << endl; - f_types_ << indent() << "case <-ctx.Done():" << endl; + f_types_ << indent() << "select {" << '\n'; + f_types_ << indent() << "case <-ctx.Done():" << '\n'; indent_up(); - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "case <-ticker.C:" << endl; + f_types_ << indent() << "case <-ticker.C:" << '\n'; indent_up(); - f_types_ << indent() << "if !iprot.Transport().IsOpen() {" << endl; + f_types_ << indent() << "if !iprot.Transport().IsOpen() {" << '\n'; indent_up(); - f_types_ << indent() << "cancel(thrift.ErrAbandonRequest)" << endl; - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "cancel(thrift.ErrAbandonRequest)" << '\n'; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}(tickerCtx, cancel)" << endl; + f_types_ << indent() << "}(tickerCtx, cancel)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } else { // Make sure we don't get the defined but unused compiling error. - f_types_ << indent() << "_ = tickerCancel" << endl << endl; + f_types_ << indent() << "_ = tickerCancel" << '\n' << '\n'; } if (!tfunction->is_oneway()) { - f_types_ << indent() << "result := " << resultname << "{}" << endl; + f_types_ << indent() << "result := " << resultname << "{}" << '\n'; } bool need_reference = type_need_reference(tfunction->get_returntype()); @@ -2908,93 +3119,108 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* f_types_ << "args." << publicize((*f_iter)->get_name()); } - f_types_ << "); err2 != nil {" << endl; + f_types_ << "); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << "tickerCancel()" << endl; - f_types_ << indent() << "err = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "tickerCancel()" << '\n'; + f_types_ << indent() << "err = thrift.WrapTException(err2)" << '\n'; t_struct* exceptions = tfunction->get_xceptions(); const vector& x_fields = exceptions->get_members(); if (!x_fields.empty()) { - f_types_ << indent() << "switch v := err2.(type) {" << endl; + f_types_ << indent() << "switch v := err2.(type) {" << '\n'; vector::const_iterator xf_iter; for (xf_iter = x_fields.begin(); xf_iter != x_fields.end(); ++xf_iter) { f_types_ << indent() << "case " << type_to_go_type(((*xf_iter)->get_type())) << ":" - << endl; + << '\n'; indent_up(); - f_types_ << indent() << "result." << publicize((*xf_iter)->get_name()) << " = v" << endl; + f_types_ << indent() << "result." << publicize((*xf_iter)->get_name()) << " = v" << '\n'; indent_down(); } - f_types_ << indent() << "default:" << endl; + f_types_ << indent() << "default:" << '\n'; indent_up(); } if (!tfunction->is_oneway()) { // Avoid writing the error to the wire if it's ErrAbandonRequest - f_types_ << indent() << "if errors.Is(err2, thrift.ErrAbandonRequest) {" << endl; + f_types_ << indent() << "if errors.Is(err2, thrift.ErrAbandonRequest) {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: thrift.WrapTException(err2)," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "if errors.Is(err2, context.Canceled) {" << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "if errors.Is(err2, context.Canceled) {" << '\n'; indent_up(); - f_types_ << indent() << "if err := context.Cause(ctx); errors.Is(err, thrift.ErrAbandonRequest) {" << endl; + f_types_ << indent() << "if err3 := context.Cause(ctx); errors.Is(err3, thrift.ErrAbandonRequest) {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(err)" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: thrift.WrapTException(err3)," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; string exc(tmp("_exc")); f_types_ << indent() << exc << " := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, " "\"Internal error processing " << escape_string(tfunction->get_name()) - << ": \" + err2.Error())" << endl; + << ": \" + err2.Error())" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) - << "\", thrift.EXCEPTION, seqId); err2 != nil {" << endl; + << "\", thrift.EXCEPTION, seqId); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := " << exc << ".Write(ctx, oprot); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageEnd(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.Flush(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if " << write_err << " != nil {" << endl; + f_types_ << indent() << "if " << write_err << " != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(" << write_err << ")" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: " << write_err << "," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; // return success=true as long as writing to the wire was successful. - f_types_ << indent() << "return true, err" << endl; + f_types_ << indent() << "return true, err" << '\n'; } if (!x_fields.empty()) { indent_down(); - f_types_ << indent() << "}" << endl; // closes switch + f_types_ << indent() << "}" << '\n'; // closes switch } indent_down(); @@ -3002,63 +3228,68 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* if (!tfunction->is_oneway()) { if (!tfunction->get_returntype()->is_void()) { - f_types_ << " else {" << endl; // make sure we set Success retval only on success + f_types_ << " else {" << '\n'; // make sure we set Success retval only on success indent_up(); f_types_ << indent() << "result.Success = "; if (need_reference) { f_types_ << "&"; } - f_types_ << "retval" << endl; + f_types_ << "retval" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } else { - f_types_ << endl; + f_types_ << '\n'; } - f_types_ << indent() << "tickerCancel()" << endl; + f_types_ << indent() << "tickerCancel()" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) << "\", thrift.REPLY, seqId); err2 != nil {" - << endl; + << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := result." << write_method_name_ << "(ctx, oprot); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageEnd(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if err2 := oprot.Flush(ctx); " << write_err << " == nil && err2 != nil {" << endl; + f_types_ << indent() << "if err2 := oprot.Flush(ctx); " << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if " << write_err << " != nil {" << endl; + f_types_ << indent() << "if " << write_err << " != nil {" << '\n'; + indent_up(); + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(" << write_err << ")" << endl; + f_types_ << indent() << "WriteError: " << write_err << "," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; // return success=true as long as writing to the wire was successful. - f_types_ << indent() << "return true, err" << endl; + f_types_ << indent() << "return true, err" << '\n'; } else { - f_types_ << endl; - f_types_ << indent() << "tickerCancel()" << endl; - f_types_ << indent() << "return true, err" << endl; + f_types_ << '\n'; + f_types_ << indent() << "tickerCancel()" << '\n'; + f_types_ << indent() << "return true, err" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } /** @@ -3096,7 +3327,7 @@ void t_go_generator::generate_deserialize_field(ostream& out, string type_name = inkey ? type_to_go_key_type(tfield->get_type()) : type_to_go_type(tfield->get_type()); - out << "var " << tfield->get_name() << " " << type_name << endl; + out << indent() << "var " << tfield->get_name() << " " << type_name << '\n'; } indent(out) << "if v, err := iprot."; @@ -3153,11 +3384,14 @@ void t_go_generator::generate_deserialize_field(ostream& out, out << "ReadI32(ctx)"; } - out << "; err != nil {" << endl; + out << "; err != nil {" << '\n'; + indent_up(); out << indent() << "return thrift.PrependError(\"error reading field " << tfield->get_key() - << ": \", err)" << endl; + << ": \", err)" << '\n'; - out << "} else {" << endl; + indent_down(); + out << indent() << "} else {" << '\n'; + indent_up(); string wrap; if (type->is_enum() || orig_type->is_typedef()) { @@ -3168,13 +3402,14 @@ void t_go_generator::generate_deserialize_field(ostream& out, string maybe_address = (is_pointer_field(tfield) ? "&" : ""); if (wrap == "") { - indent(out) << name << " = " << maybe_address << "v" << endl; + indent(out) << name << " = " << maybe_address << "v" << '\n'; } else { - indent(out) << "temp := " << wrap << "(v)" << endl; - indent(out) << name << " = " << maybe_address << "temp" << endl; + indent(out) << "temp := " << wrap << "(v)" << '\n'; + indent(out) << name << " = " << maybe_address << "temp" << '\n'; } - out << "}" << endl; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "INVALID TYPE IN generate_deserialize_field '" + type->get_name() + "' for field '" + tfield->get_name() + "'"; @@ -3193,10 +3428,12 @@ void t_go_generator::generate_deserialize_struct(ostream& out, out << indent() << prefix << eq << (pointer_field ? "&" : ""); generate_go_struct_initializer(out, tstruct); - out << indent() << "if err := " << prefix << "." << read_method_name_ << "(ctx, iprot); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T error reading struct: \", " - << prefix << "), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := " << prefix << "." << read_method_name_ << "(ctx, iprot); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T error reading struct: \", " + << prefix << "), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } /** @@ -3217,33 +3454,39 @@ void t_go_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { - out << indent() << "_, _, size, err := iprot.ReadMapBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading map begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tMap := make(" << type_to_go_type(orig_type) << ", size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tMap" << endl; + out << indent() << "_, _, size, err := iprot.ReadMapBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading map begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tMap := make(" << type_to_go_type(orig_type) << ", size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tMap" << '\n'; } else if (ttype->is_set()) { - out << indent() << "_, size, err := iprot.ReadSetBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading set begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tSet := make(" << type_to_go_type(orig_type) << ", 0, size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tSet" << endl; + out << indent() << "_, size, err := iprot.ReadSetBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading set begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tSet := make(" << type_to_go_type(orig_type) << ", 0, size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tSet" << '\n'; } else if (ttype->is_list()) { - out << indent() << "_, size, err := iprot.ReadListBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading list begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tSlice := make(" << type_to_go_type(orig_type) << ", 0, size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tSlice" << endl; + out << indent() << "_, size, err := iprot.ReadListBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading list begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tSlice := make(" << type_to_go_type(orig_type) << ", 0, size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tSlice" << '\n'; } else { throw "INVALID TYPE IN generate_deserialize_container '" + ttype->get_name() + "' for prefix '" + prefix + "'"; } // For loop iterates over elements - out << indent() << "for i := 0; i < size; i ++ {" << endl; + out << indent() << "for i := 0; i < size; i++ {" << '\n'; indent_up(); if (pointer_field) { @@ -3258,21 +3501,27 @@ void t_go_generator::generate_deserialize_container(ostream& out, } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; // Read container end if (ttype->is_map()) { - out << indent() << "if err := iprot.ReadMapEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading map end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadMapEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading map end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { - out << indent() << "if err := iprot.ReadSetEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading set end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadSetEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading set end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { - out << indent() << "if err := iprot.ReadListEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading list end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadListEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading list end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } @@ -3292,7 +3541,7 @@ void t_go_generator::generate_deserialize_map_element(ostream& out, fval.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &fkey, true, "", false, false, true); generate_deserialize_field(out, &fval, true, "", false, false, false, true); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } /** @@ -3307,7 +3556,7 @@ void t_go_generator::generate_deserialize_set_element(ostream& out, t_field felem(tset->get_elem_type(), elem); felem.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &felem, true, "", false, false, false, true); - indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << endl; + indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -3322,7 +3571,7 @@ void t_go_generator::generate_deserialize_list_element(ostream& out, t_field felem(((t_list*)tlist)->get_elem_type(), elem); felem.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &felem, true, "", false, false, false, true); - indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << endl; + indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -3406,10 +3655,13 @@ void t_go_generator::generate_serialize_field(ostream& out, out << "WriteI32(ctx, int32(" << name << "))"; } - out << "; err != nil {" << endl; + out << "; err != nil {" << '\n'; + indent_up(); out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T." << escape_string(tfield->get_name()) << " (" << tfield->get_key() - << ") field write error: \", p), err) }" << endl; + << ") field write error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "compiler error: Invalid type in generate_serialize_field '" + type->get_name() + "' for field '" + name + "'"; @@ -3424,10 +3676,12 @@ void t_go_generator::generate_serialize_field(ostream& out, */ void t_go_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << "if err := " << prefix << "." << write_method_name_ << "(ctx, oprot); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", " - << prefix << "), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := " << prefix << "." << write_method_name_ << "(ctx, oprot); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", " + << prefix << "), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } void t_go_generator::generate_serialize_container(ostream& out, @@ -3441,21 +3695,27 @@ void t_go_generator::generate_serialize_container(ostream& out, out << indent() << "if err := oprot.WriteMapBegin(ctx, " << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing map begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing map begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { out << indent() << "if err := oprot.WriteSetBegin(ctx, " << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing set begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing set begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { out << indent() << "if err := oprot.WriteListBegin(ctx, " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing list begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing list begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "compiler error: Invalid type in generate_serialize_container '" + ttype->get_name() + "' for prefix '" + prefix + "'"; @@ -3463,66 +3723,71 @@ void t_go_generator::generate_serialize_container(ostream& out, if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; - out << indent() << "for k, v := range " << prefix << " {" << endl; + out << indent() << "for k, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_map_element(out, tmap, "k", "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_set()) { t_set* tset = (t_set*)ttype; - out << indent() << "for i := 0; iget_elem_type()); - out << indent() << "if func(tgt, src " << goType << ") bool {" << endl; + out << indent() << "if func(tgt, src " << goType << ") bool {" << '\n'; indent_up(); generate_go_equals(out, tset->get_elem_type(), "tgt", "src"); - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "}(" << wrapped_prefix << "[i], " << wrapped_prefix << "[j]) {" << endl; + out << indent() << "}(" << wrapped_prefix << "[i], " << wrapped_prefix << "[j]) {" << '\n'; indent_up(); - out << indent() - << "return thrift.PrependError(\"\", fmt.Errorf(\"%T error writing set field: slice is not " - "unique\", " - << wrapped_prefix << "))" << endl; + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"%T error writing set field %q: slice is not unique\", " + << wrapped_prefix << ", \"" << escape_string(prefix) << "\"))" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "for _, v := range " << prefix << " {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "for _, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_set_element(out, tset, "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_list()) { t_list* tlist = (t_list*)ttype; - out << indent() << "for _, v := range " << prefix << " {" << endl; + out << indent() << "for _, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_list_element(out, tlist, "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (ttype->is_map()) { - out << indent() << "if err := oprot.WriteMapEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing map end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteMapEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing map end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { - out << indent() << "if err := oprot.WriteSetEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing set end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteSetEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing set end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { - out << indent() << "if err := oprot.WriteListEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing list end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteListEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing list end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } @@ -3609,7 +3874,7 @@ void t_go_generator::generate_go_equals(ostream& out, t_type* ori_type, string t out << tgt << " != " << src; } - out << " { return false }" << endl; + out << " { return false }" << '\n'; } else { throw "compiler error: Invalid type in generate_go_equals '" + ttype->get_name() + "' for '" + tgt + "'"; @@ -3625,7 +3890,7 @@ void t_go_generator::generate_go_equals_struct(ostream& out, string src) { (void)ttype; out << indent() << "if !" << tgt << "." << equals_method_name_ << "(" << src - << ") { return false }" << endl; + << ") { return false }" << '\n'; } /** @@ -3635,16 +3900,16 @@ void t_go_generator::generate_go_equals_container(ostream& out, t_type* ttype, string tgt, string src) { - out << indent() << "if len(" << tgt << ") != len(" << src << ") { return false }" << endl; + out << indent() << "if len(" << tgt << ") != len(" << src << ") { return false }" << '\n'; if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; - out << indent() << "for k, _tgt := range " << tgt << " {" << endl; + out << indent() << "for k, _tgt := range " << tgt << " {" << '\n'; indent_up(); string element_source = tmp("_src"); - out << indent() << element_source << " := " << src << "[k]" << endl; + out << indent() << element_source << " := " << src << "[k]" << '\n'; generate_go_equals(out, tmap->get_val_type(), "_tgt", element_source); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_list() || ttype->is_set()) { t_type* elem; if (ttype->is_list()) { @@ -3654,13 +3919,13 @@ void t_go_generator::generate_go_equals_container(ostream& out, t_set* temp = (t_set*)ttype; elem = temp->get_elem_type(); } - out << indent() << "for i, _tgt := range " << tgt << " {" << endl; + out << indent() << "for i, _tgt := range " << tgt << " {" << '\n'; indent_up(); string element_source = tmp("_src"); - out << indent() << element_source << " := " << src << "[i]" << endl; + out << indent() << element_source << " := " << src << "[i]" << '\n'; generate_go_equals(out, elem, "_tgt", element_source); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { throw "INVALID TYPE IN generate_go_equals_container '" + ttype->get_name(); } @@ -3699,7 +3964,7 @@ void t_go_generator::generate_go_docstring(ostream& out, if (fields.size() > 0) { if (has_doc) { - ss << endl; + ss << '\n'; } has_doc = true; @@ -3713,9 +3978,10 @@ void t_go_generator::generate_go_docstring(ostream& out, if (p->has_doc()) { ss << ": " << p->get_doc(); } else { - ss << endl; + ss << '\n'; } } + ss << '\n'; } if (has_doc) { @@ -4097,6 +4363,32 @@ void t_go_generator::parse_go_tags(map* tags, const string in) { } } +void t_go_generator::generate_deprecation_comment(ostream& out, const map>& annotations) { + auto iter = annotations.find("deprecated"); + if (annotations.end() != iter) { + out << indent() << "// Deprecated: "; + + bool first = true; + for (auto str_iter = iter->second.begin(); str_iter != iter->second.end(); ++str_iter) { + if (*str_iter == "1") { + // Empty annotations will generate "1", skip those. + continue; + } + if (first) { + first = false; + } else { + out << "; "; + } + out << *str_iter; + } + if (first) { + // All deprecation annotations are empty, put a generic reason here + out << "(no reason given)"; + } + out << '\n'; + } +} + bool format_go_output(const string& file_path) { // formatting via gofmt deactivated due to THRIFT-3893 diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.h b/compiler/cpp/src/thrift/generate/t_go_generator.h index a67485c5506..72825bc9caa 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.h +++ b/compiler/cpp/src/thrift/generate/t_go_generator.h @@ -44,8 +44,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - const string DEFAULT_THRIFT_IMPORT = "github.com/apache/thrift/lib/go/thrift"; static std::string package_flag; @@ -268,6 +266,8 @@ class t_go_generator : public t_generator { std::string type_to_go_key_type(t_type* ttype); std::string type_to_spec_args(t_type* ttype); + void generate_deprecation_comment(std::ostream& os, const std::map>& annotations); + void indent_up() { t_generator::indent_up(); } void indent_down() { t_generator::indent_down(); } std::string indent() { return t_generator::indent(); } @@ -288,6 +288,10 @@ class t_go_generator : public t_generator { static bool is_pointer_field(t_field* tfield, bool in_container = false); + std::string indent_str() const override { + return "\t"; + } + private: std::string gen_package_prefix_; std::string gen_thrift_import_; diff --git a/compiler/cpp/src/thrift/generate/t_gv_generator.cc b/compiler/cpp/src/thrift/generate/t_gv_generator.cc index f8616ffb345..c91200b4916 100644 --- a/compiler/cpp/src/thrift/generate/t_gv_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_gv_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Graphviz code generator */ @@ -110,10 +108,10 @@ void t_gv_generator::init_generator() { MKDIR(get_out_dir().c_str()); string fname = get_out_dir() + program_->get_name() + ".gv"; f_out_.open(fname.c_str()); - f_out_ << "digraph \"" << escape_string(program_name_) << "\" {" << endl; - f_out_ << "node [style=filled, shape=record];" << endl; - f_out_ << "edge [arrowsize=0.5];" << endl; - f_out_ << "rankdir=LR" << endl; + f_out_ << "digraph \"" << escape_string(program_name_) << "\" {" << '\n'; + f_out_ << "node [style=filled, shape=record];" << '\n'; + f_out_ << "edge [arrowsize=0.5];" << '\n'; + f_out_ << "rankdir=LR" << '\n'; } /** @@ -126,29 +124,29 @@ void t_gv_generator::close_generator() { // Print edges std::list::iterator iter = edges.begin(); for (; iter != edges.end(); iter++) { - f_out_ << (*iter) << endl; + f_out_ << (*iter) << '\n'; } // Print graph end } and close file - f_out_ << "}" << endl; + f_out_ << "}" << '\n'; f_out_.close(); } void t_gv_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); - f_out_ << "node [fillcolor=azure];" << endl; + f_out_ << "node [fillcolor=azure];" << '\n'; f_out_ << name << " [label=\""; f_out_ << escape_string(name); f_out_ << " :: "; print_type(ttypedef->get_type(), name); - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); - f_out_ << "node [fillcolor=white];" << endl; + f_out_ << "node [fillcolor=white];" << '\n'; f_out_ << name << " [label=\"enum " << escape_string(name); vector values = tenum->get_constants(); @@ -159,13 +157,13 @@ void t_gv_generator::generate_enum(t_enum* tenum) { f_out_ << (*val_iter)->get_value(); } - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); - f_out_ << "node [fillcolor=aliceblue];" << endl; + f_out_ << "node [fillcolor=aliceblue];" << '\n'; f_out_ << "const_" << name << " [label=\""; f_out_ << escape_string(name); @@ -174,22 +172,22 @@ void t_gv_generator::generate_const(t_const* tconst) { f_out_ << " :: "; print_type(tconst->get_type(), "const_" + name); - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_struct(t_struct* tstruct) { string name = tstruct->get_name(); if (tstruct->is_xception()) { - f_out_ << "node [fillcolor=lightpink];" << endl; + f_out_ << "node [fillcolor=lightpink];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "exception " << escape_string(name); } else if (tstruct->is_union()) { - f_out_ << "node [fillcolor=lightcyan];" << endl; + f_out_ << "node [fillcolor=lightcyan];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "union " << escape_string(name); } else { - f_out_ << "node [fillcolor=beige];" << endl; + f_out_ << "node [fillcolor=beige];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "struct " << escape_string(name); } @@ -208,7 +206,7 @@ void t_gv_generator::generate_struct(t_struct* tstruct) { print_type((*mem_iter)->get_type(), name + ":field_" + field_name); } - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::print_type(t_type* ttype, string struct_field_ref) { @@ -296,10 +294,10 @@ void t_gv_generator::print_const_value(t_type* type, t_const_value* tvalue) { void t_gv_generator::generate_service(t_service* tservice) { string service_name = get_service_name(tservice); - f_out_ << "subgraph cluster_" << service_name << " {" << endl; - f_out_ << "node [fillcolor=bisque];" << endl; - f_out_ << "style=dashed;" << endl; - f_out_ << "label = \"" << escape_string(service_name) << " service\";" << endl; + f_out_ << "subgraph cluster_" << service_name << " {" << '\n'; + f_out_ << "node [fillcolor=bisque];" << '\n'; + f_out_ << "style=dashed;" << '\n'; + f_out_ << "label = \"" << escape_string(service_name) << " service\";" << '\n'; // TODO: service extends @@ -327,7 +325,7 @@ void t_gv_generator::generate_service(t_service* tservice) { "function_" + service_name + fn_name + ":param_" + (*arg_iter)->get_name()); } // end of node - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; // Exception edges if (exception_arrows) { @@ -340,7 +338,7 @@ void t_gv_generator::generate_service(t_service* tservice) { } } - f_out_ << " }" << endl; + f_out_ << " }" << '\n'; } std::string t_gv_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc index b236e0bc619..94f7f541d72 100644 --- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Haxe code generator. * @@ -99,16 +97,16 @@ class t_haxe_generator : public t_oop_generator { t_const_value* value); void render_struct_initializer(std::ostream& out, - t_struct* type, + t_struct* type, t_const_value* value); void render_map_initializer(std::ostream& out, - t_map* type, + t_map* type, t_const_value* value); void render_list_initializer(std::ostream& out, - t_list* type, + t_list* type, t_const_value* value); void render_set_initializer(std::ostream& out, - t_set* type, + t_set* type, t_const_value* value); // helper @@ -424,10 +422,10 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and package it - f_enum << autogen_comment() << haxe_package() << ";" << endl << endl; + f_enum << autogen_comment() << haxe_package() << ";" << '\n' << '\n'; // Add haxe imports - f_enum << string() + "import org.apache.thrift.helper.*;" << endl << endl; + f_enum << string() + "import org.apache.thrift.helper.*;" << '\n' << '\n'; generate_rtti_decoration(f_enum); generate_macro_decoration(f_enum); @@ -439,11 +437,11 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); indent(f_enum) << "public static inline var " << (*c_iter)->get_name() << " : Int = " << value - << ";" << endl; + << ";" << '\n'; } // Create a static Set with all valid values for this enum - f_enum << endl; + f_enum << '\n'; indent(f_enum) << "public static var VALID_VALUES = { new IntSet( ["; indent_up(); @@ -454,19 +452,19 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { firstValue = false; } indent_down(); - f_enum << "]); };" << endl; + f_enum << "]); };" << '\n'; indent(f_enum) << "public static var VALUES_TO_NAMES = { ["; indent_up(); firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { - f_enum << (firstValue ? "" : ",") << endl; + f_enum << (firstValue ? "" : ",") << '\n'; indent(f_enum) << (*c_iter)->get_name() << " => \"" << (*c_iter)->get_name() << "\""; firstValue = false; } - f_enum << endl; + f_enum << '\n'; indent_down(); - indent(f_enum) << "]; };" << endl; + indent(f_enum) << "]; };" << '\n'; scope_down(f_enum); // end class @@ -486,15 +484,15 @@ void t_haxe_generator::generate_consts(std::vector consts) { f_consts.open(f_consts_name.c_str()); // Print header - f_consts << autogen_comment() << haxe_package() << ";" << endl << endl; + f_consts << autogen_comment() << haxe_package() << ";" << '\n' << '\n'; - f_consts << endl; + f_consts << '\n'; f_consts << haxe_type_imports(); generate_rtti_decoration(f_consts); generate_macro_decoration(f_consts); - indent(f_consts) << "class " << get_cap_name(program_name_) << "Constants {" << endl << endl; + indent(f_consts) << "class " << get_cap_name(program_name_) << "Constants {" << '\n' << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -504,7 +502,7 @@ void t_haxe_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -527,7 +525,7 @@ void t_haxe_generator::print_const_value(std::ostream& out, } out << " : " << get_cap_name(type_name(type)) << " = "; render_const_value(out, type, value); - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; } std::string t_haxe_generator::render_const_value_str( t_type* type, t_const_value* value) { @@ -594,9 +592,9 @@ void t_haxe_generator::render_const_value(std::ostream& out, void t_haxe_generator::render_struct_initializer(std::ostream& out, t_struct* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -615,24 +613,24 @@ void t_haxe_generator::render_struct_initializer(std::ostream& out, } indent(out) << "tmp." << v_iter->first->get_string() << " = "; render_const_value(out, field_type, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } - indent(out) << "return tmp;" << endl; + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_map_initializer(std::ostream& out, t_map* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); - + const map& values = value->get_map(); map::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { @@ -640,56 +638,56 @@ void t_haxe_generator::render_map_initializer(std::ostream& out, render_const_value(out, key_type, v_iter->first); out << ", "; render_const_value(out, val_type, v_iter->second); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_list_initializer(std::ostream& out, t_list* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* elm_type = type->get_elem_type(); - + const vector& values = value->get_list(); vector::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { indent(out) << "tmp.add("; render_const_value(out, elm_type, *v_iter); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_set_initializer(std::ostream& out, t_set* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* elm_type = type->get_elem_type(); - + const vector& values = value->get_list(); vector::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { indent(out) << "tmp.add("; render_const_value(out, elm_type, *v_iter); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } @@ -723,14 +721,14 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception ofstream_with_content_based_conditional_update f_struct; f_struct.open(f_struct_name.c_str()); - f_struct << autogen_comment() << haxe_package() << ";" << endl; + f_struct << autogen_comment() << haxe_package() << ";" << '\n'; - f_struct << endl; + f_struct << '\n'; string imports; f_struct << haxe_type_imports() << haxe_thrift_imports() - << haxe_thrift_gen_imports(tstruct, imports) << endl; + << haxe_thrift_gen_imports(tstruct, imports) << '\n'; generate_haxe_struct_definition(f_struct, tstruct, is_exception, is_result); @@ -762,11 +760,11 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, if (is_exception) { out << "extends TException "; } - out << "implements TBase {" << endl << endl; + out << "implements TBase {" << '\n' << '\n'; indent_up(); indent(out) << "static var STRUCT_DESC = { new TStruct(\"" << tstruct->get_name() << "\"); };" - << endl; + << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; @@ -775,69 +773,69 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, indent(out) << "static var " << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = { new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " << (*m_iter)->get_key() << "); };" - << endl; + << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_haxe_doc(out, *m_iter); // indent(out) << "private var _" << (*m_iter)->get_name() + " : " + - // type_name((*m_iter)->get_type()) << ";" << endl; - indent(out) << "@:isVar" << endl; + // type_name((*m_iter)->get_type()) << ";" << '\n'; + indent(out) << "@:isVar" << '\n'; indent(out) << "public var " << (*m_iter)->get_name() + "(get,set) : " - + get_cap_name(type_name((*m_iter)->get_type())) << ";" << endl; + + get_cap_name(type_name((*m_iter)->get_type())) << ";" << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "inline static var " << upcase_string((*m_iter)->get_name()) - << "_FIELD_ID : Int = " << (*m_iter)->get_key() << ";" << endl; + << "_FIELD_ID : Int = " << (*m_iter)->get_key() << ";" << '\n'; } - out << endl; + out << '\n'; // Inner Isset class if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private var __isset_" << (*m_iter)->get_name() << " : Bool = false;" - << endl; + << '\n'; } } } - out << endl; + out << '\n'; // Static initializer to populate global class to struct metadata map if (false) { // TODO: reactivate when needed generate_haxe_meta_data_map(out, tstruct); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); indent(out) << "FieldMetaData.addStructMetaDataMap(" << type_name(tstruct) << ", metaDataMap);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; + indent(out) << "}" << '\n'; } // Default constructor - indent(out) << "public function new() {" << endl; + indent(out) << "public function new() {" << '\n'; indent_up(); if (is_exception) { - indent(out) << "super();" << endl; + indent(out) << "super();" << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_value() != nullptr) { indent(out) << "this." << (*m_iter)->get_name() << " = "; render_const_value( out, (*m_iter)->get_type(), (*m_iter)->get_value()); - out << ";" << endl; + out << ";" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; generate_property_getters_setters(out, tstruct); generate_generic_field_getters_setters(out, tstruct); @@ -852,7 +850,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, generate_haxe_struct_tostring(out, tstruct, is_exception); generate_haxe_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -861,123 +859,123 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public function read( iprot : TProtocol) : Void {" << endl; + out << indent() << "public function read( iprot : TProtocol) : Void {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "iprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "iprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); // Declare stack tmp variables and read struct header - out << indent() << "var field : TField;" << endl << indent() << "iprot.readStructBegin();" - << endl; + out << indent() << "var field : TField;" << '\n' << indent() << "iprot.readStructBegin();" + << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (field.type == TType.STOP) { " << endl; + indent(out) << "if (field.type == TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (field.id)" << endl; + indent(out) << "switch (field.id)" << '\n'; scope_up(out); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << upcase_string((*f_iter)->get_name()) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string((*f_iter)->get_name()) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); generate_isset_set(out, *f_iter); indent_down(); - out << indent() << "} else { " << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl << indent() << "}" << endl; + out << indent() << "} else { " << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n' << indent() << "}" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "default:" << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl; + out << indent() << "default:" << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n'; scope_down(out); // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; scope_down(out); - out << indent() << "iprot.readStructEnd();" << endl << endl; + out << indent() << "iprot.readStructEnd();" << '\n' << '\n'; - indent(out) << "iprot.DecrementRecursionDepth();" << endl; + indent(out) << "iprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "iprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "iprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); // check for required fields of primitive type // (which can be checked here but not in the general validate method) - out << endl << indent() << "// check for required fields of primitive type, which can't be " - "checked in the validate method" << endl; + out << '\n' << indent() << "// check for required fields of primitive type, which can't be " + "checked in the validate method" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { - out << indent() << "if (!__isset_" << (*f_iter)->get_name() << ") {" << endl << indent() + out << indent() << "if (!__isset_" << (*f_iter)->get_name() << ") {" << '\n' << indent() << " throw new TProtocolException(TProtocolException.UNKNOWN, \"Required field '" << (*f_iter)->get_name() - << "' was not found in serialized data! Struct: \" + toString());" << endl << indent() - << "}" << endl; + << "' was not found in serialized data! Struct: \" + toString());" << '\n' << indent() + << "}" << '\n'; } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // generates haxe method to perform various checks // (e.g. check that all required fields are set) void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public function validate() : Void {" << endl; + indent(out) << "public function validate() : Void {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if (type_can_be_null((*f_iter)->get_type())) { - indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << endl; + indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << '\n'; indent(out) << " throw new TProtocolException(TProtocolException.UNKNOWN, \"Required field '" - << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << endl; - indent(out) << "}" << endl; + << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << '\n'; + indent(out) << "}" << '\n'; } else { indent(out) << "// alas, we cannot check '" << (*f_iter)->get_name() - << "' because it's a primitive." << endl; + << "' because it's a primitive." << '\n'; } } } // check that fields of type enum have valid values - out << indent() << "// check that fields of type enum have valid values" << endl; + out << indent() << "// check that fields of type enum have valid values" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); t_type* type = field->get_type(); @@ -985,18 +983,18 @@ void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) if (type->is_enum()) { indent(out) << "if (" << generate_isset_check(field) << " && !" << get_cap_name(get_enum_class_name(type)) << ".VALID_VALUES.contains(" - << field->get_name() << ")){" << endl; + << field->get_name() << ")){" << '\n'; indent_up(); indent(out) << "throw new TProtocolException(TProtocolException.UNKNOWN, \"The field '" << field->get_name() << "' has been assigned the invalid value \" + " - << field->get_name() << ");" << endl; + << field->get_name() << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1005,7 +1003,7 @@ void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public function write(oprot:TProtocol) : Void {" << endl; + out << indent() << "public function write(oprot:TProtocol) : Void {" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1013,57 +1011,57 @@ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstru vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; - indent(out) << "oprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "validate();" << '\n'; + indent(out) << "oprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl; + out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } - indent(out) << "oprot.writeFieldStop();" << endl; - indent(out) << "oprot.writeStructEnd();" << endl; + indent(out) << "oprot.writeFieldStop();" << '\n'; + indent(out) << "oprot.writeStructEnd();" << '\n'; - indent(out) << "oprot.DecrementRecursionDepth();" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "oprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1075,59 +1073,59 @@ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstru * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public function write(oprot:TProtocol) : Void {" << endl; + out << indent() << "public function write(oprot:TProtocol) : Void {" << '\n'; indent_up(); string name = tstruct->get_name(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "oprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this." << generate_isset_check(*f_iter) << ") {" << endl; + out << "(this." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } - indent(out) << endl; - indent(out) << "oprot.writeFieldStop();" << endl; - indent(out) << "oprot.writeStructEnd();" << endl; + indent(out) << '\n'; + indent(out) << "oprot.writeFieldStop();" << '\n'; + indent(out) << "oprot.writeStructEnd();" << '\n'; - indent(out) << "oprot.DecrementRecursionDepth();" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "oprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_haxe_generator::generate_reflection_getters(ostringstream& out, @@ -1136,9 +1134,9 @@ void t_haxe_generator::generate_reflection_getters(ostringstream& out, string cap_name) { (void)type; (void)cap_name; - indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); } @@ -1148,13 +1146,13 @@ void t_haxe_generator::generate_reflection_setters(ostringstream& out, string cap_name) { (void)type; (void)cap_name; - indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; - indent(out) << " this." << field_name << " = value;" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; + indent(out) << " this." << field_name << " = value;" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent_down(); } @@ -1181,39 +1179,39 @@ void t_haxe_generator::generate_generic_field_getters_setters(std::ostream& out, } // create the setter - indent(out) << "public function setFieldValue(fieldID : Int, value : Dynamic) : Void {" << endl; + indent(out) << "public function setFieldValue(fieldID : Int, value : Dynamic) : Void {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; out << setter_stream.str(); - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // create the getter - indent(out) << "public function getFieldValue(fieldID : Int) : Dynamic {" << endl; + indent(out) << "public function getFieldValue(fieldID : Int) : Dynamic {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; out << getter_stream.str(); - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Creates a generic isSet method that takes the field number as argument @@ -1223,29 +1221,29 @@ void t_haxe_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "// Returns true if field corresponding to fieldID is set (has been assigned a " - "value) and false otherwise" << endl; - indent(out) << "public function isSet(fieldID : Int) : Bool {" << endl; + "value) and false otherwise" << '\n'; + indent(out) << "public function isSet(fieldID : Int) : Bool {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << upcase_string(field->get_name()) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field->get_name()) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1265,48 +1263,48 @@ void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct* // Simple getter generate_haxe_doc(out, field); indent(out) << "public function get_" << field_name << "() : " << get_cap_name(type_name(type)) - << " {" << endl; + << " {" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Simple setter generate_haxe_doc(out, field); indent(out) << "public function set_" << field_name << "(" << field_name << ":" << get_cap_name(type_name(type)) << ") : " << get_cap_name(type_name(type)) << " {" - << endl; + << '\n'; indent_up(); - indent(out) << "this." << field_name << " = " << field_name << ";" << endl; + indent(out) << "this." << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter - indent(out) << "public function unset" << cap_name << "() : Void {" << endl; + indent(out) << "public function unset" << cap_name << "() : Void {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "this.__isset_" << field_name << " = false;" << endl; + indent(out) << "this.__isset_" << field_name << " = false;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "// Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise" << endl; - indent(out) << "public function is" << get_cap_name("set") << cap_name << "() : Bool {" << endl; + << " is set (has been assigned a value) and false otherwise" << '\n'; + indent(out) << "public function is" << get_cap_name("set") << cap_name << "() : Bool {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << field_name << " != null;" << endl; + indent(out) << "return this." << field_name << " != null;" << '\n'; } else { - indent(out) << "return this.__isset_" << field_name << ";" << endl; + indent(out) << "return this.__isset_" << field_name << ";" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -1320,11 +1318,11 @@ void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tst if( is_override) { out << "override "; } - out << "function toString() : String {" << endl; + out << "function toString() : String {" << '\n'; indent_up(); - out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << endl; - out << indent() << "var first : Bool = true;" << endl << endl; + out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << '\n'; + out << indent() << "var first : Bool = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1332,58 +1330,58 @@ void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tst for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) ret += \", \";" << endl; + indent(out) << "if (!first) ret += \", \";" << '\n'; } - indent(out) << "ret += \"" << (*f_iter)->get_name() << ":\";" << endl; + indent(out) << "ret += \"" << (*f_iter)->get_name() << ":\";" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << endl; - indent(out) << " ret += \"null\";" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << '\n'; + indent(out) << " ret += \"null\";" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (field->get_type()->is_binary()) { - indent(out) << " ret += \"BINARY\";" << endl; + indent(out) << " ret += \"BINARY\";" << '\n'; } else if (field->get_type()->is_enum()) { indent(out) << "var " << field->get_name() << "_name : String = " << get_cap_name(get_enum_class_name(field->get_type())) - << ".VALUES_TO_NAMES[this." << (*f_iter)->get_name() << "];" << endl; - indent(out) << "if (" << field->get_name() << "_name != null) {" << endl; - indent(out) << " ret += " << field->get_name() << "_name;" << endl; - indent(out) << " ret += \" (\";" << endl; - indent(out) << "}" << endl; - indent(out) << "ret += this." << field->get_name() << ";" << endl; - indent(out) << "if (" << field->get_name() << "_name != null) {" << endl; - indent(out) << " ret += \")\";" << endl; - indent(out) << "}" << endl; + << ".VALUES_TO_NAMES[this." << (*f_iter)->get_name() << "];" << '\n'; + indent(out) << "if (" << field->get_name() << "_name != null) {" << '\n'; + indent(out) << " ret += " << field->get_name() << "_name;" << '\n'; + indent(out) << " ret += \" (\";" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "ret += this." << field->get_name() << ";" << '\n'; + indent(out) << "if (" << field->get_name() << "_name != null) {" << '\n'; + indent(out) << " ret += \")\";" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "ret += this." << (*f_iter)->get_name() << ";" << endl; + indent(out) << "ret += this." << (*f_iter)->get_name() << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "ret += \")\";" << endl << indent() << "return ret;" << endl; + out << indent() << "ret += \")\";" << '\n' << indent() << "return ret;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1397,7 +1395,7 @@ void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstru vector::const_iterator f_iter; // Static Map with fieldID -> FieldMetaData mappings - indent(out) << "inline static var metaDataMap : IntMap = new IntMap();" << endl; + indent(out) << "inline static var metaDataMap : IntMap = new IntMap();" << '\n'; if (fields.size() > 0) { // Populate map @@ -1419,7 +1417,7 @@ void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstru // Create value meta data generate_field_value_meta_data(out, field->get_type()); - out << ");" << endl; + out << ");" << '\n'; } scope_down(out); } @@ -1484,7 +1482,7 @@ std::string t_haxe_generator::get_haxe_type_string(t_type* type) { } void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { - out << endl; + out << '\n'; indent_up(); indent_up(); if (type->is_struct()) { @@ -1527,20 +1525,20 @@ void t_haxe_generator::generate_service(t_service* tservice) { string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "_service.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n'; - f_service_ << endl << haxe_type_imports() << haxe_thrift_imports() + f_service_ << '\n' << haxe_type_imports() << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice); if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << "_service;" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << "_service;" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_interface(tservice,false); f_service_.close(); @@ -1549,20 +1547,20 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n'; - f_service_ << endl << haxe_type_imports() << haxe_thrift_imports() + f_service_ << '\n' << haxe_type_imports() << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice); if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << ";" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << ";" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_interface(tservice,true); f_service_.close(); @@ -1571,18 +1569,18 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Impl.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl << endl << haxe_type_imports() - << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n' << '\n' << haxe_type_imports() + << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << '\n'; if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << "Impl;" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << "Impl;" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_client(tservice); f_service_.close(); @@ -1594,17 +1592,17 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Processor.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl - << endl + f_service_ << autogen_comment() << haxe_package() << ";" << '\n' + << '\n' << haxe_type_imports() - << haxe_thrift_imports() - << haxe_thrift_gen_imports(tservice) - << endl; + << haxe_thrift_imports() + << haxe_thrift_gen_imports(tservice) + << '\n'; if (!package_name_.empty()) { - f_service_ << "import " << package_name_ << ".*;" << endl; - f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << endl; - f_service_ << endl; + f_service_ << "import " << package_name_ << ".*;" << '\n'; + f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << '\n'; + f_service_ << '\n'; } generate_service_server(tservice); @@ -1668,9 +1666,9 @@ void t_haxe_generator::generate_service_method_signature_normal(t_function* tfun bool is_interface) { if (is_interface) { generate_deprecation_attribute(f_service_, tfunction, true); - indent(f_service_) << function_signature_normal(tfunction) << ";" << endl << endl; + indent(f_service_) << function_signature_normal(tfunction) << ";" << '\n' << '\n'; } else { - indent(f_service_) << "public " << function_signature_normal(tfunction) << " {" << endl; + indent(f_service_) << "public " << function_signature_normal(tfunction) << " {" << '\n'; } } @@ -1683,15 +1681,15 @@ void t_haxe_generator::generate_service_method_signature_combined(t_function* tf bool is_interface) { if (!tfunction->is_oneway()) { std::string on_success_impl = generate_service_method_onsuccess(tfunction, false, false); - indent(f_service_) << "// function onError(Dynamic) : Void;" << endl; - indent(f_service_) << "// function " << on_success_impl.c_str() << ";" << endl; + indent(f_service_) << "// function onError(Dynamic) : Void;" << '\n'; + indent(f_service_) << "// function " << on_success_impl.c_str() << ";" << '\n'; } if (is_interface) { generate_deprecation_attribute(f_service_, tfunction, false); - indent(f_service_) << function_signature_combined(tfunction) << ";" << endl << endl; + indent(f_service_) << function_signature_combined(tfunction) << ";" << '\n' << '\n'; } else { - indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << endl; + indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << '\n'; } } @@ -1738,7 +1736,7 @@ void t_haxe_generator::generate_deprecation_attribute(ostream& out, t_function* } } - out << endl; + out << '\n'; } } @@ -1762,14 +1760,14 @@ void t_haxe_generator::generate_service_interface(t_service* tservice, bool comb generate_rtti_decoration(f_service_); generate_macro_decoration(f_service_); f_service_ << indent() << "interface " << get_cap_name(service_name_) << cbk_postfix << extends_iface << " {" - << endl << endl; + << '\n' << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_haxe_doc(f_service_, *f_iter); generate_service_method_signature(*f_iter, true, combined); } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -1778,7 +1776,7 @@ void t_haxe_generator::generate_service_interface(t_service* tservice, bool comb * @param tservice The service */ void t_haxe_generator::generate_service_helpers(t_service* tservice) { - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1804,44 +1802,44 @@ void t_haxe_generator::generate_service_client(t_service* tservice) { generate_rtti_decoration(f_service_); // build macro is inherited from interface indent(f_service_) << "class " << get_cap_name(service_name_) << "Impl" << extends_client - << " implements " << get_cap_name(service_name_) << " {" << endl << endl; + << " implements " << get_cap_name(service_name_) << " {" << '\n' << '\n'; indent_up(); - indent(f_service_) << "public function new( iprot : TProtocol, oprot : TProtocol = null)" << endl; + indent(f_service_) << "public function new( iprot : TProtocol, oprot : TProtocol = null)" << '\n'; scope_up(f_service_); if (extends.empty()) { - f_service_ << indent() << "iprot_ = iprot;" << endl; - f_service_ << indent() << "if (oprot == null) {" << endl; + f_service_ << indent() << "iprot_ = iprot;" << '\n'; + f_service_ << indent() << "if (oprot == null) {" << '\n'; indent_up(); - f_service_ << indent() << "oprot_ = iprot;" << endl; + f_service_ << indent() << "oprot_ = iprot;" << '\n'; indent_down(); - f_service_ << indent() << "} else {" << endl; + f_service_ << indent() << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "oprot_ = oprot;" << endl; + f_service_ << indent() << "oprot_ = oprot;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } else { - f_service_ << indent() << "super(iprot, oprot);" << endl; + f_service_ << indent() << "super(iprot, oprot);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - f_service_ << indent() << "private var iprot_ : TProtocol;" << endl << indent() - << "private var oprot_ : TProtocol;" << endl << indent() - << "private var seqid_ : Int;" << endl << endl; + f_service_ << indent() << "private var iprot_ : TProtocol;" << '\n' << indent() + << "private var oprot_ : TProtocol;" << '\n' << indent() + << "private var seqid_ : Int;" << '\n' << '\n'; - indent(f_service_) << "public function getInputProtocol() : TProtocol" << endl; + indent(f_service_) << "public function getInputProtocol() : TProtocol" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.iprot_;" << endl; + indent(f_service_) << "return this.iprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public function getOutputProtocol() : TProtocol" << endl; + indent(f_service_) << "public function getOutputProtocol() : TProtocol" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.oprot_;" << endl; + indent(f_service_) << "return this.oprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate client method implementations @@ -1866,140 +1864,140 @@ void t_haxe_generator::generate_service_client(t_service* tservice) { string args = tmp("args"); string calltype = (*f_iter)->is_oneway() ? "ONEWAY" : "CALL"; f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname - << "\", TMessageType." << calltype << ", seqid_));" << endl << indent() - << "var " << args << " : " << argsname << " = new " << argsname << "();" << endl; + << "\", TMessageType." << calltype << ", seqid_));" << '\n' << indent() + << "var " << args << " : " << argsname << " = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << args << "." << (*fld_iter)->get_name() << " = " - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } - f_service_ << indent() << args << ".write(oprot_);" << endl << indent() - << "oprot_.writeMessageEnd();" << endl; + f_service_ << indent() << args << ".write(oprot_);" << '\n' << indent() + << "oprot_.writeMessageEnd();" << '\n'; string retval = tmp("retval"); if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) { f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype()) - << " = " << render_default_value_for_type((*f_iter)->get_returntype(),true) - << ";" << endl; + << " = " << render_default_value_for_type((*f_iter)->get_returntype(),true) + << ";" << '\n'; } if ((*f_iter)->is_oneway()) { - f_service_ << indent() << "oprot_.getTransport().flush();" << endl; + f_service_ << indent() << "oprot_.getTransport().flush();" << '\n'; } else { - indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << endl; + indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << '\n'; indent_up(); - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent_up(); string appex = tmp("appex"); - indent(f_service_) << "var " << appex << " : TApplicationException;" << endl; + indent(f_service_) << "var " << appex << " : TApplicationException;" << '\n'; string resultname = get_cap_name((*f_iter)->get_name() + "_result"); - indent(f_service_) << "if (error != null) {" << endl; + indent(f_service_) << "if (error != null) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw error;" << endl; + indent(f_service_) << "throw error;" << '\n'; indent_down(); - indent(f_service_) << "onError(error);" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(error);" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; string msg = tmp("msg"); - indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << endl; - indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << endl; + indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << '\n'; + indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << '\n'; indent_up(); - indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << endl; - indent(f_service_) << "iprot_.readMessageEnd();" << endl; - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << '\n'; + indent(f_service_) << "iprot_.readMessageEnd();" << '\n'; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << appex << ";" << endl; + indent(f_service_) << "throw " << appex << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << appex << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << appex << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; string result = tmp("result"); - indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << endl; - indent(f_service_) << "" << result << ".read(iprot_);" << endl; - indent(f_service_) << "iprot_.readMessageEnd();" << endl; + indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << '\n'; + indent(f_service_) << "" << result << ".read(iprot_);" << '\n'; + indent(f_service_) << "iprot_.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << endl; + indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << '\n'; indent_up(); - indent(f_service_) << "if (onSuccess != null)" << endl; + indent(f_service_) << "if (onSuccess != null)" << '\n'; indent_up(); - indent(f_service_) << "onSuccess(" << result << ".success);" << endl; + indent(f_service_) << "onSuccess(" << result << ".success);" << '\n'; indent_down(); - indent(f_service_) << retval << " = " << result << ".success;" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << retval << " = " << result << ".success;" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << endl; + indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << endl; + indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "if (onSuccess != null)" << endl; + indent(f_service_) << "if (onSuccess != null)" << '\n'; indent_up(); - indent(f_service_) << "onSuccess();" << endl; + indent(f_service_) << "onSuccess();" << '\n'; indent_down(); - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << appex << " = new TApplicationException(" << "TApplicationException.MISSING_RESULT," - << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl; - indent(f_service_) << "if (onError == null)" << endl; + << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << appex << ";" << endl; + indent(f_service_) << "throw " << appex << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << appex << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << appex << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; } indent_down(); - indent(f_service_) << endl; - indent(f_service_) << "} catch( e : TException) {" << endl; + indent(f_service_) << '\n'; + indent(f_service_) << "} catch( e : TException) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw e;" << endl; + indent(f_service_) << "throw e;" << '\n'; indent_down(); - indent(f_service_) << "onError(e);" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(e);" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "});" << endl << endl; + indent(f_service_) << "});" << '\n' << '\n'; } if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) { - f_service_ << indent() << "return " << retval << ";" << endl; + f_service_ << indent() << "return " << retval << ";" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } /** @@ -2024,35 +2022,35 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { generate_rtti_decoration(f_service_); generate_macro_decoration(f_service_); indent(f_service_) << "class " << get_cap_name(service_name_) << "Processor" << extends_processor - << " implements TProcessor {" << endl << endl; + << " implements TProcessor {" << '\n' << '\n'; indent_up(); f_service_ << indent() << "private var " << get_cap_name(service_name_) - << "_iface_ : " << get_cap_name(service_name_) << "_service;" << endl; + << "_iface_ : " << get_cap_name(service_name_) << "_service;" << '\n'; if (extends.empty()) { f_service_ << indent() << "private var PROCESS_MAP = new StringMap< Int->TProtocol->TProtocol->Void >();" - << endl; + << '\n'; } - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << "_service)" - << endl; + << '\n'; scope_up(f_service_); if (!extends.empty()) { - f_service_ << indent() << "super(iface);" << endl; + f_service_ << indent() << "super(iface);" << '\n'; } - f_service_ << indent() << get_cap_name(service_name_) << "_iface_ = iface;" << endl; + f_service_ << indent() << get_cap_name(service_name_) << "_iface_ = iface;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "PROCESS_MAP.set(\"" << (*f_iter)->get_name() << "\", " - << (*f_iter)->get_name() << "());" << endl; + << (*f_iter)->get_name() << "());" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation string override = ""; @@ -2061,31 +2059,31 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { } indent(f_service_) << override << "public function process( iprot : TProtocol, oprot : TProtocol) : Bool" - << endl; + << '\n'; scope_up(f_service_); - f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << endl; + f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << '\n'; // TODO(mcslee): validate message, was the seqid etc. legit? f_service_ - << indent() << "var fn = PROCESS_MAP.get(msg.name);" << endl - << indent() << "if (fn == null) {" << endl - << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);" << endl - << indent() << " iprot.readMessageEnd();" << endl + << indent() << "var fn = PROCESS_MAP.get(msg.name);" << '\n' + << indent() << "if (fn == null) {" << '\n' + << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n' + << indent() << " iprot.readMessageEnd();" << '\n' << indent() << " var appex = new TApplicationException(TApplicationException.UNKNOWN_METHOD, " - << "\"Invalid method name: '\"+msg.name+\"'\");" << endl - << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl - << indent() << " appex.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();" << endl - << indent() << " oprot.getTransport().flush();" << endl - << indent() << " return true;" << endl << indent() << "}" << endl - << indent() << "fn( msg.seqid, iprot, oprot);" << endl + << "\"Invalid method name: '\"+msg.name+\"'\");" << '\n' + << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << '\n' + << indent() << " appex.write(oprot);" << '\n' << indent() << " oprot.writeMessageEnd();" << '\n' + << indent() << " oprot.getTransport().flush();" << '\n' + << indent() << " return true;" << '\n' << indent() << "}" << '\n' + << indent() << "fn( msg.seqid, iprot, oprot);" << '\n' ; - f_service_ << indent() << "return true;" << endl; + f_service_ << indent() << "return true;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2093,7 +2091,7 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -2132,20 +2130,20 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function (void)tservice; // Open class indent(f_service_) << "private function " << tfunction->get_name() - << "() : Int->TProtocol->TProtocol->Void {" << endl; + << "() : Int->TProtocol->TProtocol->Void {" << '\n'; indent_up(); // Open function indent(f_service_) << "return function( seqid : Int, iprot : TProtocol, oprot : TProtocol) : Void" - << endl; + << '\n'; scope_up(f_service_); string argsname = get_cap_name(tfunction->get_name() + "_args"); string resultname = get_cap_name(tfunction->get_name() + "_result"); - f_service_ << indent() << "var args : " << argsname << " = new " << argsname << "();" << endl - << indent() << "args.read(iprot);" << endl << indent() << "iprot.readMessageEnd();" - << endl; + f_service_ << indent() << "var args : " << argsname << " = new " << argsname << "();" << '\n' + << indent() << "args.read(iprot);" << '\n' << indent() << "iprot.readMessageEnd();" + << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2153,11 +2151,11 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << endl; + f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << '\n'; } // Try block for any function to catch (defined or undefined) exceptions - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); @@ -2182,7 +2180,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); f_service_ << indent() << "}"; @@ -2190,11 +2188,11 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // catch exceptions defined in the IDL for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << (*x_iter)->get_name() << ":" - << get_cap_name(type_name((*x_iter)->get_type(), false, false)) << ") {" << endl; + << get_cap_name(type_name((*x_iter)->get_type(), false, false)) << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << (*x_iter)->get_name() << " = " - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { @@ -2205,45 +2203,45 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // always catch all exceptions to prevent from service denial string appex = tmp("appex"); - f_service_ << " catch (th : Dynamic) {" << endl; + f_service_ << " catch (th : Dynamic) {" << '\n'; indent_up(); - indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl; + indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << '\n'; if (!tfunction->is_oneway()) { indent(f_service_) << "var appex = new TApplicationException(TApplicationException.INTERNAL_ERROR, " - "\"Internal error processing " << tfunction->get_name() << "\");" << endl; + "\"Internal error processing " << tfunction->get_name() << "\");" << '\n'; indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.EXCEPTION, seqid));" << endl; - indent(f_service_) << "appex.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.EXCEPTION, seqid));" << '\n'; + indent(f_service_) << "appex.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.getTransport().flush();" << '\n'; } - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; scope_down(f_service_); // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; return; } f_service_ << indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl << indent() << "result.write(oprot);" - << endl << indent() << "oprot.writeMessageEnd();" << endl << indent() - << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n' << indent() << "result.write(oprot);" + << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' << indent() + << "oprot.getTransport().flush();" << '\n'; // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -2309,7 +2307,7 @@ void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "readI32();"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2323,8 +2321,8 @@ void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, void t_haxe_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl - << indent() << prefix << ".read(iprot);" << endl; + out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << '\n' + << indent() << prefix << ".read(iprot);" << '\n'; } /** @@ -2345,21 +2343,21 @@ void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Declare variables, read header if (ttype->is_map()) { - indent(out) << "var " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "var " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "var " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readListBegin();" << '\n'; } indent(out) << prefix << " = new " << type_name(ttype, false, true) // size the collection correctly << "(" - << ");" << endl; + << ");" << '\n'; // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for( " << i << " in 0 ... " << obj << ".size)" << endl; + indent(out) << "for( " << i << " in 0 ... " << obj << ".size)" << '\n'; scope_up(out); @@ -2375,11 +2373,11 @@ void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -2394,13 +2392,13 @@ void t_haxe_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << ".set( " << key << ", " << val << ");" << endl; + indent(out) << prefix << ".set( " << key << ", " << val << ");" << '\n'; } /** @@ -2410,11 +2408,11 @@ void t_haxe_generator::generate_deserialize_set_element(ostream& out, t_set* tse string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -2426,11 +2424,11 @@ void t_haxe_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -2496,7 +2494,7 @@ void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2513,7 +2511,7 @@ void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_haxe_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -2527,30 +2525,30 @@ void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { string iter = tmp("_key"); string counter = tmp("_sizeCounter"); - indent(out) << "var " << counter << " : Int = 0;" << endl; - indent(out) << "for( " << iter << " in " << prefix << ") {" << endl; - indent(out) << " " << counter << +"++;" << endl; - indent(out) << "}" << endl; + indent(out) << "var " << counter << " : Int = 0;" << '\n'; + indent(out) << "for( " << iter << " in " << prefix << ") {" << '\n'; + indent(out) << " " << counter << +"++;" << '\n'; + indent(out) << "}" << '\n'; indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << counter << "));" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".size));" << endl; + << ", " << prefix << ".size));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".length));" - << endl; + << '\n'; } string iter = tmp("elem"); if (ttype->is_map()) { - indent(out) << "for( " << iter << " in " << prefix << ".keys())" << endl; + indent(out) << "for( " << iter << " in " << prefix << ".keys())" << '\n'; } else if (ttype->is_set()) { - indent(out) << "for( " << iter << " in " << prefix << ".toArray())" << endl; + indent(out) << "for( " << iter << " in " << prefix << ".toArray())" << '\n'; } else if (ttype->is_list()) { - indent(out) << "for( " << iter << " in " << prefix << ")" << endl; + indent(out) << "for( " << iter << " in " << prefix << ")" << '\n'; } scope_up(out); @@ -2566,11 +2564,11 @@ void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } } @@ -3006,7 +3004,7 @@ string t_haxe_generator::constant_name(string name) { */ void t_haxe_generator::generate_rtti_decoration(ostream& out) { if (rtti_) { - out << "@:rtti" << endl; + out << "@:rtti" << '\n'; } } @@ -3015,10 +3013,10 @@ void t_haxe_generator::generate_rtti_decoration(ostream& out) { */ void t_haxe_generator::generate_macro_decoration(ostream& out) { if (!buildmacro_.empty()) { - out << "#if ! macro" << endl; - out << "@:build( " << buildmacro_ << ")" << endl; // current class/interface - out << "@:autoBuild( " << buildmacro_ << ")" << endl; // inherited classes/interfaces - out << "#end" << endl; + out << "#if ! macro" << '\n'; + out << "@:build( " << buildmacro_ << ")" << '\n'; // current class/interface + out << "@:autoBuild( " << buildmacro_ << ")" << '\n'; // inherited classes/interfaces + out << "#end" << '\n'; } } @@ -3061,7 +3059,7 @@ std::string t_haxe_generator::generate_isset_check(std::string field_name) { void t_haxe_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { - indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl; + indent(out) << "this.__isset_" << field->get_name() << " = true;" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_html_generator.cc b/compiler/cpp/src/thrift/generate/t_html_generator.cc index 15a0401d596..637cd885eff 100644 --- a/compiler/cpp/src/thrift/generate/t_html_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_html_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; /** @@ -129,9 +127,9 @@ class t_html_generator : public t_generator { void t_html_generator::generate_program_toc() { f_out_ << "" - << "" << endl; + << "" << '\n'; generate_program_toc_row(program_); - f_out_ << "
ModuleServicesData typesConstants
Data typesConstants
" << endl; + f_out_ << "" << '\n'; } /** @@ -159,15 +157,15 @@ void t_html_generator::generate_program_toc_rows(t_program* tprog, */ void t_html_generator::generate_program_toc_row(t_program* tprog) { string fname = tprog->get_name() + ".html"; - f_out_ << "" << endl << "" << tprog->get_name() << ""; + f_out_ << "" << '\n' << "" << tprog->get_name() << ""; if (!tprog->get_services().empty()) { vector services = tprog->get_services(); vector::iterator sv_iter; for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { string name = get_service_name(*sv_iter); f_out_ << "" << name - << "
" << endl; - f_out_ << "
    " << endl; + << "
    " << '\n'; + f_out_ << "
      " << '\n'; map fn_html; vector functions = (*sv_iter)->get_functions(); vector::iterator fn_iter; @@ -178,12 +176,12 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { fn_html.insert(pair(fn_name, html)); } for (auto & html_iter : fn_html) { - f_out_ << html_iter.second << endl; + f_out_ << html_iter.second << '\n'; } - f_out_ << "
    " << endl; + f_out_ << "
" << '\n'; } } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; map data_types; if (!tprog->get_enums().empty()) { vector enums = tprog->get_enums(); @@ -191,7 +189,7 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) { string name = (*en_iter)->get_name(); // f_out_ << "" << name - // << "
" << endl; + // << "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); } @@ -202,7 +200,7 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) { string name = (*td_iter)->get_symbolic(); // f_out_ << "" << name - // << "
" << endl; + // << "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); @@ -214,16 +212,16 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { string name = (*o_iter)->get_name(); // f_out_ << "" << name - //<< "
" << endl; + //<< "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); } } for (auto & data_type : data_types) { - f_out_ << data_type.second << "
" << endl; + f_out_ << data_type.second << "
" << '\n'; } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; if (!tprog->get_consts().empty()) { map const_html; vector consts = tprog->get_consts(); @@ -235,10 +233,10 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { const_html.insert(pair(name, html)); } for (auto & con_iter : const_html) { - f_out_ << con_iter.second << "
" << endl; + f_out_ << con_iter.second << "
" << '\n'; } } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; } /** @@ -251,30 +249,30 @@ void t_html_generator::generate_program() { current_file_ = program_->get_name() + ".html"; string fname = get_out_dir() + current_file_; f_out_.open(fname.c_str()); - f_out_ << "" << endl; - f_out_ << "" << endl; - f_out_ << "" << endl; - f_out_ << "" << endl; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; generate_style_tag(); - f_out_ << "Thrift module: " << program_->get_name() << "" << endl - << "
" << endl - << "

Thrift module: " << program_->get_name() << "

" << endl; + f_out_ << "Thrift module: " << program_->get_name() << "" << '\n' + << "
" << '\n' + << "

Thrift module: " << program_->get_name() << "

" << '\n'; print_doc(program_); generate_program_toc(); if (!program_->get_consts().empty()) { - f_out_ << "

Constants

" << endl; + f_out_ << "

Constants

" << '\n'; vector consts = program_->get_consts(); f_out_ << ""; - f_out_ << "" << endl; + f_out_ << "" << '\n'; generate_consts(consts); f_out_ << "
ConstantTypeValue
ConstantTypeValue
"; } if (!program_->get_enums().empty()) { - f_out_ << "

Enumerations

" << endl; + f_out_ << "

Enumerations

" << '\n'; // Generate enums vector enums = program_->get_enums(); vector::iterator en_iter; @@ -284,7 +282,7 @@ void t_html_generator::generate_program() { } if (!program_->get_typedefs().empty()) { - f_out_ << "

Type declarations

" << endl; + f_out_ << "

Type declarations

" << '\n'; // Generate typedefs vector typedefs = program_->get_typedefs(); vector::iterator td_iter; @@ -294,7 +292,7 @@ void t_html_generator::generate_program() { } if (!program_->get_objects().empty()) { - f_out_ << "

Data structures

" << endl; + f_out_ << "

Data structures

" << '\n'; // Generate structs and exceptions in declared order vector objects = program_->get_objects(); vector::iterator o_iter; @@ -308,7 +306,7 @@ void t_html_generator::generate_program() { } if (!program_->get_services().empty()) { - f_out_ << "

Services

" << endl; + f_out_ << "

Services

" << '\n'; // Generate services vector services = program_->get_services(); vector::iterator sv_iter; @@ -318,7 +316,7 @@ void t_html_generator::generate_program() { } } - f_out_ << "
" << endl; + f_out_ << "
" << '\n'; f_out_.close(); generate_index(); @@ -332,17 +330,17 @@ void t_html_generator::generate_index() { current_file_ = "index.html"; string index_fname = get_out_dir() + current_file_; f_out_.open(index_fname.c_str()); - f_out_ << "" << endl << "" << endl; + f_out_ << "" << '\n' << "" << '\n'; generate_style_tag(); - f_out_ << "All Thrift declarations" << endl - << "
" << endl << "

All Thrift declarations

" << endl; + f_out_ << "All Thrift declarations" << '\n' + << "
" << '\n' << "

All Thrift declarations

" << '\n'; f_out_ << "" - << "" << endl; + << "" << '\n'; vector programs; generate_program_toc_rows(program_, programs); - f_out_ << "
ModuleServicesData typesConstants
Constants
" << endl; - f_out_ << "
" << endl; + f_out_ << "" << '\n'; + f_out_ << "
" << '\n'; f_out_.close(); } @@ -357,17 +355,17 @@ void t_html_generator::generate_css() { } void t_html_generator::generate_css_content(std::ostream& f_target) { - f_target << BOOTSTRAP_CSS() << endl; - f_target << "/* Auto-generated CSS for generated Thrift docs */" << endl; - f_target << "h3, h4 { margin-bottom: 6px; }" << endl; + f_target << BOOTSTRAP_CSS() << '\n'; + f_target << "/* Auto-generated CSS for generated Thrift docs */" << '\n'; + f_target << "h3, h4 { margin-bottom: 6px; }" << '\n'; f_target << "div.definition { border: 1px solid #CCC; margin-bottom: 10px; padding: 10px; }" - << endl; - f_target << "div.extends { margin: -0.5em 0 1em 5em }" << endl; - f_target << "td { vertical-align: top; }" << endl; - f_target << "table { empty-cells: show; }" << endl; - f_target << "code { line-height: 20px; }" << endl; + << '\n'; + f_target << "div.extends { margin: -0.5em 0 1em 5em }" << '\n'; + f_target << "td { vertical-align: top; }" << '\n'; + f_target << "table { empty-cells: show; }" << '\n'; + f_target << "code { line-height: 20px; }" << '\n'; f_target << ".table-bordered th, .table-bordered td { border-bottom: 1px solid #DDDDDD; }" - << endl; + << '\n'; } /** @@ -377,11 +375,11 @@ void t_html_generator::generate_css_content(std::ostream& f_target) { */ void t_html_generator::generate_style_tag() { if (!standalone_) { - f_out_ << "" << endl; + f_out_ << "" << '\n'; } else { - f_out_ << "" << endl; + f_out_ << "-->" << '\n'; } } @@ -856,14 +854,14 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { if (has_docs) { arg_iter = args.begin(); f_out_ << "

get_name() - << "\">Parameters

" << endl; + << "\">Parameters" << '\n'; f_out_ << ""; f_out_ << ""; for (; arg_iter != args.end(); arg_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
NameDescription
" << (*arg_iter)->get_name(); f_out_ << ""; f_out_ << escape_html((*arg_iter)->get_doc()); - f_out_ << "
"; } @@ -880,14 +878,14 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { if (has_docs) { ex_iter = excepts.begin(); f_out_ << "

get_name() - << "\">Exceptions

" << endl; + << "\">Exceptions" << '\n'; f_out_ << ""; f_out_ << ""; for (; ex_iter != excepts.end(); ex_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
TypeDescription
" << (*ex_iter)->get_type()->get_name(); f_out_ << ""; f_out_ << escape_html((*ex_iter)->get_doc()); - f_out_ << "
"; } @@ -902,12 +900,12 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { void t_html_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); f_out_ << "
"; - f_out_ << "

Typedef: " << name << "

" << endl; + f_out_ << "

Typedef: " << name << "

" << '\n'; f_out_ << "

Base type: "; print_type(ttypedef->get_type()); - f_out_ << "

" << endl; + f_out_ << "

" << '\n'; print_doc(ttypedef); - f_out_ << "
" << endl; + f_out_ << "" << '\n'; } /** @@ -918,21 +916,21 @@ void t_html_generator::generate_typedef(t_typedef* ttypedef) { void t_html_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); f_out_ << "
"; - f_out_ << "

Enumeration: " << name << "

" << endl; + f_out_ << "

Enumeration: " << name << "

" << '\n'; print_doc(tenum); vector values = tenum->get_constants(); vector::iterator val_iter; - f_out_ << "
" << endl; + f_out_ << "
" << '\n'; for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } - f_out_ << "
"; f_out_ << (*val_iter)->get_name(); f_out_ << ""; f_out_ << (*val_iter)->get_value(); - f_out_ << "" << endl; + f_out_ << "" << '\n'; print_doc((*val_iter)); - f_out_ << "
" << endl; + f_out_ << "" << '\n'; } /** @@ -968,12 +966,12 @@ void t_html_generator::generate_struct(t_struct* tstruct) { } else { f_out_ << "Struct: "; } - f_out_ << name << "" << endl; + f_out_ << name << "" << '\n'; vector members = tstruct->get_members(); vector::iterator mem_iter = members.begin(); f_out_ << ""; f_out_ << "" << endl; + "th>" << '\n'; for (; mem_iter != members.end(); mem_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
KeyFieldTypeDescriptionRequirednessDefault value
Default value
" << (*mem_iter)->get_key() << ""; f_out_ << (*mem_iter)->get_name(); @@ -996,7 +994,7 @@ void t_html_generator::generate_struct(t_struct* tstruct) { print_const_value((*mem_iter)->get_type(), default_val); f_out_ << ""; } - f_out_ << "

"; print_doc(tstruct); @@ -1018,7 +1016,7 @@ void t_html_generator::generate_xception(t_struct* txception) { * @param tservice The service definition */ void t_html_generator::generate_service(t_service* tservice) { - f_out_ << "

Service: " << service_name_ << "

" << endl; + f_out_ << "

Service: " << service_name_ << "

" << '\n'; if (tservice->get_extends()) { f_out_ << "
extends "; @@ -1032,7 +1030,7 @@ void t_html_generator::generate_service(t_service* tservice) { string fn_name = (*fn_iter)->get_name(); f_out_ << "
"; f_out_ << "

Function: " << service_name_ - << "." << fn_name << "

" << endl; + << "." << fn_name << "" << '\n'; f_out_ << "
";
     std::string::size_type offset = print_type((*fn_iter)->get_returntype());
     bool first = true;
@@ -1042,7 +1040,7 @@ void t_html_generator::generate_service(t_service* tservice) {
     vector::iterator arg_iter = args.begin();
     for (; arg_iter != args.end(); arg_iter++) {
       if (!first) {
-        f_out_ << "," << endl;
+        f_out_ << "," << '\n';
         for (std::string::size_type i = 0; i < offset; ++i) {
           f_out_ << " ";
         }
@@ -1055,7 +1053,7 @@ void t_html_generator::generate_service(t_service* tservice) {
         print_const_value((*arg_iter)->get_type(), (*arg_iter)->get_value());
       }
     }
-    f_out_ << ")" << endl;
+    f_out_ << ")" << '\n';
     first = true;
     vector excepts = (*fn_iter)->get_xceptions()->get_members();
     vector::iterator ex_iter = excepts.begin();
@@ -1068,7 +1066,7 @@ void t_html_generator::generate_service(t_service* tservice) {
         first = false;
         print_type((*ex_iter)->get_type());
       }
-      f_out_ << endl;
+      f_out_ << '\n';
     }
     f_out_ << "
"; print_doc(*fn_iter); diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc index d7e0b65939c..3524ada81ce 100644 --- a/compiler/cpp/src/thrift/generate/t_java_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc @@ -45,8 +45,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string thrift_option_class = "org.apache.thrift.Option"; static const string jdk_option_class = "java.util.Optional"; @@ -511,8 +509,7 @@ string t_java_generator::java_package() { } string t_java_generator::java_suppressions() { - return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})" - + endl; + return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n"; } string t_java_generator::java_nullable_annotation() { @@ -567,7 +564,7 @@ void t_java_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and package it - f_enum << autogen_comment() << java_package() << endl; + f_enum << autogen_comment() << java_package() << '\n'; generate_java_doc(f_enum, tenum); @@ -576,7 +573,7 @@ void t_java_generator::generate_enum(t_enum* tenum) { } if (is_deprecated) { - indent(f_enum) << "@Deprecated" << endl; + indent(f_enum) << "@Deprecated" << '\n'; } indent(f_enum) << "public enum " << tenum->get_name() << " implements org.apache.thrift.TEnum "; scope_up(f_enum); @@ -590,62 +587,62 @@ void t_java_generator::generate_enum(t_enum* tenum) { if (first) { first = false; } else { - f_enum << "," << endl; + f_enum << "," << '\n'; } generate_java_doc(f_enum, *c_iter); if (this->is_deprecated((*c_iter)->annotations_)) { - indent(f_enum) << "@Deprecated" << endl; + indent(f_enum) << "@Deprecated" << '\n'; } indent(f_enum) << (*c_iter)->get_name() << "(" << value << ")"; } - f_enum << ";" << endl << endl; + f_enum << ";" << '\n' << '\n'; // Field for thriftCode - indent(f_enum) << "private final int value;" << endl << endl; + indent(f_enum) << "private final int value;" << '\n' << '\n'; - indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << endl; - indent(f_enum) << " this.value = value;" << endl; - indent(f_enum) << "}" << endl << endl; + indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << '\n'; + indent(f_enum) << " this.value = value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Get the integer value of this enum value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << java_override_annotation() << endl; - indent(f_enum) << "public int getValue() {" << endl; - indent(f_enum) << " return value;" << endl; - indent(f_enum) << "}" << endl << endl; - - indent(f_enum) << "/**" << endl; + << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << java_override_annotation() << '\n'; + indent(f_enum) << "public int getValue() {" << '\n'; + indent(f_enum) << " return value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; + + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Find a the enum type by its integer value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " * @return null if the value is not found." << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << java_nullable_annotation() << endl; - indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << endl; + << '\n'; + indent(f_enum) << " * @return null if the value is not found." << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << java_nullable_annotation() << '\n'; + indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << '\n'; indent_up(); - indent(f_enum) << "switch (value) {" << endl; + indent(f_enum) << "switch (value) {" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << "case " << value << ":" << endl; - indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << endl; + indent(f_enum) << "case " << value << ":" << '\n'; + indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << '\n'; } - indent(f_enum) << "default:" << endl; - indent(f_enum) << " return null;" << endl; + indent(f_enum) << "default:" << '\n'; + indent(f_enum) << " return null;" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; scope_down(f_enum); @@ -667,8 +664,8 @@ void t_java_generator::generate_consts(std::vector consts) { // Print header f_consts << autogen_comment() << java_package() << java_suppressions(); - f_consts << "public class " << make_valid_java_identifier(program_name_) << "Constants {" << endl - << endl; + f_consts << "public class " << make_valid_java_identifier(program_name_) << "Constants {" << '\n' + << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -677,7 +674,7 @@ void t_java_generator::generate_consts(std::vector consts) { (*c_iter)->get_value(), false); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -700,9 +697,9 @@ void t_java_generator::print_const_value(std::ostream& out, } if (type->is_base_type()) { string v2 = render_const_value(out, type, value); - out << name << " = " << v2 << ";" << endl << endl; + out << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { - out << name << " = " << render_const_value(out, type, value) << ";" << endl << endl; + out << name << " = " << render_const_value(out, type, value) << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& unsorted_fields = ((t_struct*)type)->get_members(); vector fields = unsorted_fields; @@ -710,9 +707,9 @@ void t_java_generator::print_const_value(std::ostream& out, vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { @@ -728,22 +725,22 @@ void t_java_generator::print_const_value(std::ostream& out, string val = render_const_value(out, field_type, v_iter->second); indent(out) << name << "."; std::string cap_name = get_cap_name(v_iter->first->get_string()); - out << "set" << cap_name << "(" << val << ");" << endl; + out << "set" << cap_name << "(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_map()) { std::string constructor_args; if (is_enum_map(type)) { constructor_args = inner_enum_type_name(type); } out << name << " = new " << type_name(type, false, true) << "(" << constructor_args << ");" - << endl; + << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* ktype = ((t_map*)type)->get_key_type(); @@ -753,22 +750,22 @@ void t_java_generator::print_const_value(std::ostream& out, for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string key = render_const_value(out, ktype, v_iter->first); string val = render_const_value(out, vtype, v_iter->second); - indent(out) << name << ".put(" << key << ", " << val << ");" << endl; + indent(out) << name << ".put(" << key << ", " << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { if (is_enum_set(type)) { out << name << " = " << type_name(type, false, true, true) << ".noneOf(" - << inner_enum_type_name(type) << ");" << endl; + << inner_enum_type_name(type) << ");" << '\n'; } else { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; } if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* etype; @@ -781,13 +778,13 @@ void t_java_generator::print_const_value(std::ostream& out, vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, etype, *v_iter); - indent(out) << name << ".add(" << val << ");" << endl; + indent(out) << name << ".add(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else { throw "compiler error: no const of type " + type->get_name(); } @@ -916,7 +913,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { } if (is_deprecated) { - indent(f_struct) << "@Deprecated" << endl; + indent(f_struct) << "@Deprecated" << '\n'; } indent(f_struct) << "public " << (is_final ? "final " : "") << "class " << make_valid_java_identifier(tstruct->get_name()) << " extends org.apache.thrift.TUnion<" << make_valid_java_identifier(tstruct->get_name()) << ", " @@ -927,49 +924,49 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { generate_struct_desc(f_struct, tstruct); generate_field_descs(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_field_name_constants(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_meta_data_map(f_struct, tstruct); generate_union_constructor(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_abstract_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_field_by_id(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_getters_and_setters(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_is_set_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_comparisons(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_hashcode(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_write_object(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_read_object(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; scope_down(f_struct); @@ -980,63 +977,63 @@ void t_java_generator::generate_union_constructor(ostream& out, t_struct* tstruc const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "public " << type_name(tstruct) << "() {" << endl; + indent(out) << "public " << type_name(tstruct) << "() {" << '\n'; indent_up(); bool default_value = false; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr) { indent(out) << "super(_Fields." << constant_name((*m_iter)->get_name()) << ", " - << render_const_value(out, type, (*m_iter)->get_value()) << ");" << endl; + << render_const_value(out, type, (*m_iter)->get_value()) << ");" << '\n'; default_value = true; break; } } if (default_value == false) { - indent(out) << "super();" << endl; + indent(out) << "super();" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(_Fields setField, java.lang.Object value) {" - << endl; - indent(out) << " super(setField, value);" << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << " super(setField, value);" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(" << type_name(tstruct) << " other) {" - << endl; - indent(out) << " super(other);" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " super(other);" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; // generate "constructors" for each field for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = (*m_iter)->get_type(); indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" - << type_name(type) << " value) {" << endl; - indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl; - indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << endl; - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + << type_name(type) << " value) {" << '\n'; + indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << '\n'; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; if (type->is_binary()) { indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() - << "(byte[] value) {" << endl; + << "(byte[] value) {" << '\n'; indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" - << endl; + << '\n'; indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()); if (unsafe_binaries_) { - indent(out) << "(java.nio.ByteBuffer.wrap(value));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value));" << '\n'; } else { - indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << '\n'; } - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; } } } @@ -1050,7 +1047,7 @@ void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct if (first) { first = false; } else { - out << endl; + out << '\n'; } t_field* field = (*m_iter); @@ -1061,95 +1058,95 @@ void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public byte[] get" << cap_name << "() {" << endl; + indent(out) << "public byte[] get" << cap_name << "() {" << '\n'; indent(out) << " set" << cap_name << "(org.apache.thrift.TBaseHelper.rightSize(buffer" - << get_cap_name("for") << cap_name << "()));" << endl; + << get_cap_name("for") << cap_name << "()));" << '\n'; indent(out) << " java.nio.ByteBuffer b = buffer" << get_cap_name("for") << cap_name << "();" - << endl; - indent(out) << " return b == null ? null : b.array();" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " return b == null ? null : b.array();" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; indent(out) << "public java.nio.ByteBuffer buffer" << get_cap_name("for") - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; if (unsafe_binaries_) { - indent(out) << " return (java.nio.ByteBuffer)getFieldValue();" << endl; + indent(out) << " return (java.nio.ByteBuffer)getFieldValue();" << '\n'; } else { indent(out) << " return " "org.apache.thrift.TBaseHelper.copyBinary((java.nio.ByteBuffer)getFieldValue());" - << endl; + << '\n'; } - indent(out) << " } else {" << endl; + indent(out) << " } else {" << '\n'; indent(out) << " throw new java.lang.RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public " << type_name(field->get_type()) << " get" - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" - << endl; - indent(out) << " } else {" << endl; + << '\n'; + indent(out) << " } else {" << '\n'; indent(out) << " throw new java.lang.RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << get_cap_name(field->get_name()) << "(byte[] value) {" - << endl; + << '\n'; indent(out) << " set" << get_cap_name(field->get_name()); if (unsafe_binaries_) { - indent(out) << "(java.nio.ByteBuffer.wrap(value));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value));" << '\n'; } else { - indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << get_cap_name(field->get_name()) << "(" - << type_name(field->get_type()) << " value) {" << endl; + << type_name(field->get_type()) << " value) {" << '\n'; - indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << endl; + indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << '\n'; if (type_can_be_null(field->get_type())) { indent(out) << " value_ = java.util.Objects.requireNonNull(value,\"" - << "_Fields." << constant_name(field->get_name()) << "\");" << endl; + << "_Fields." << constant_name(field->get_name()) << "\");" << '\n'; } else { - indent(out) << " value_ = value;" << endl; + indent(out) << " value_ = value;" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -1162,49 +1159,49 @@ void t_java_generator::generate_union_is_set_methods(ostream& out, t_struct* tst if (first) { first = false; } else { - out << endl; + out << '\n'; } std::string field_name = (*m_iter)->get_name(); indent(out) << "public boolean is" << get_cap_name("set") << get_cap_name(field_name) << "() {" - << endl; + << '\n'; indent_up(); - indent(out) << "return setField_ == _Fields." << constant_name(field_name) << ";" << endl; + indent(out) << "return setField_ == _Fields." << constant_name(field_name) << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } void t_java_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) { generate_check_type(out, tstruct); - out << endl; + out << '\n'; generate_standard_scheme_read_value(out, tstruct); - out << endl; + out << '\n'; generate_standard_scheme_write_value(out, tstruct); - out << endl; + out << '\n'; generate_tuple_scheme_read_value(out, tstruct); - out << endl; + out << '\n'; generate_tuple_scheme_write_value(out, tstruct); - out << endl; + out << '\n'; generate_get_field_desc(out, tstruct); - out << endl; + out << '\n'; generate_get_struct_desc(out, tstruct); - out << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "protected _Fields enumForId(short id) {" << endl; - indent(out) << " return _Fields.findByThriftIdOrThrow(id);" << endl; - indent(out) << "}" << endl; + out << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "protected _Fields enumForId(short id) {" << '\n'; + indent(out) << " return _Fields.findByThriftIdOrThrow(id);" << '\n'; + indent(out) << "}" << '\n'; } void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void checkType(_Fields setField, java.lang.Object value) throws " "java.lang.ClassCastException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1213,42 +1210,42 @@ void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent(out) << " if (value instanceof " << type_name(field->get_type(), true, false, true) - << ") {" << endl; - indent(out) << " break;" << endl; - indent(out) << " }" << endl; + << ") {" << '\n'; + indent(out) << " break;" << '\n'; + indent(out) << " }" << '\n'; indent(out) << " throw new java.lang.ClassCastException(\"Was expecting value of type " << type_name(field->get_type(), true, false) << " for field '" << field->get_name() - << "', but got \" + value.getClass().getSimpleName());" << endl; + << "', but got \" + value.getClass().getSimpleName());" << '\n'; // do the real check here } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalArgumentException(\"Unknown field id \" + setField);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected java.lang.Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol " "iprot, org.apache.thrift.protocol.TField field) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1257,53 +1254,53 @@ void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struc for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << constant_name(field->get_name()) << "_FIELD_DESC.type) {" - << endl; + << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); - indent(out) << "} else {" << endl; - indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << " return null;" << endl; - indent(out) << "}" << endl; + indent(out) << "} else {" << '\n'; + indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << " return null;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"setField wasn't null, but didn't match any " "of the case statements!\");" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "return null;" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol " "oprot) throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1312,42 +1309,42 @@ void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_stru for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"Cannot write union with unknown field \" + " "setField_);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected java.lang.Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol " "iprot, short fieldID) throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(fieldID);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(fieldID);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1356,45 +1353,45 @@ void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"setField wasn't null, but didn't match any " "of the case statements!\");" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); indent(out) << "throw new org.apache.thrift.protocol.TProtocolException(\"Couldn't find a field " "with field id \" + fieldID);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) " "throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1403,119 +1400,119 @@ void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"Cannot write union with unknown field \" + " "setField_);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) {" - << endl; + << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; - indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; + indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << '\n'; } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalArgumentException(\"Unknown field id \" + setField);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_override_annotation() << endl; - indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << endl; - indent(out) << " return STRUCT_DESC;" << endl; - indent(out) << "}" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << '\n'; + indent(out) << " return STRUCT_DESC;" << '\n'; + indent(out) << "}" << '\n'; } void t_java_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) { // equality - indent(out) << "public boolean equals(java.lang.Object other) {" << endl; - indent(out) << " if (other instanceof " << make_valid_java_identifier(tstruct->get_name()) << ") {" << endl; - indent(out) << " return equals((" << make_valid_java_identifier(tstruct->get_name()) << ")other);" << endl; - indent(out) << " } else {" << endl; - indent(out) << " return false;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << "public boolean equals(java.lang.Object other) {" << '\n'; + indent(out) << " if (other instanceof " << make_valid_java_identifier(tstruct->get_name()) << ") {" << '\n'; + indent(out) << " return equals((" << make_valid_java_identifier(tstruct->get_name()) << ")other);" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " return false;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; - indent(out) << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" << endl; + indent(out) << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" << '\n'; indent(out) << " return other != null && getSetField() == other.getSetField() && " "getFieldValue().equals(other.getFieldValue());" - << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << java_override_annotation() << endl; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent(out) << " int lastComparison = org.apache.thrift.TBaseHelper.compareTo(getSetField(), " "other.getSetField());" - << endl; - indent(out) << " if (lastComparison == 0) {" << endl; + << '\n'; + indent(out) << " if (lastComparison == 0) {" << '\n'; indent(out) << " return org.apache.thrift.TBaseHelper.compareTo(getFieldValue(), " "other.getFieldValue());" - << endl; - indent(out) << " }" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; } void t_java_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_override_annotation() << endl; - indent(out) << "public int hashCode() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int hashCode() {" << '\n'; indent(out) << " java.util.List list = new java.util.ArrayList();" - << endl; - indent(out) << " list.add(this.getClass().getName());" << endl; - indent(out) << " org.apache.thrift.TFieldIdEnum setField = getSetField();" << endl; - indent(out) << " if (setField != null) {" << endl; - indent(out) << " list.add(setField.getThriftFieldId());" << endl; - indent(out) << " java.lang.Object value = getFieldValue();" << endl; - indent(out) << " if (value instanceof org.apache.thrift.TEnum) {" << endl; - indent(out) << " list.add(((org.apache.thrift.TEnum)getFieldValue()).getValue());" << endl; - indent(out) << " } else {" << endl; - indent(out) << " list.add(value);" << endl; - indent(out) << " }" << endl; - indent(out) << " }" << endl; - indent(out) << " return list.hashCode();" << endl; + << '\n'; + indent(out) << " list.add(this.getClass().getName());" << '\n'; + indent(out) << " org.apache.thrift.TFieldIdEnum setField = getSetField();" << '\n'; + indent(out) << " if (setField != null) {" << '\n'; + indent(out) << " list.add(setField.getThriftFieldId());" << '\n'; + indent(out) << " java.lang.Object value = getFieldValue();" << '\n'; + indent(out) << " if (value instanceof org.apache.thrift.TEnum) {" << '\n'; + indent(out) << " list.add(((org.apache.thrift.TEnum)getFieldValue()).getValue());" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " list.add(value);" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return list.hashCode();" << '\n'; indent(out) << "}"; } @@ -1545,7 +1542,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public " << (is_final ? "final " : "") << (in_class ? "static " : "") << "class " << make_valid_java_identifier(tstruct->get_name()) << " "; @@ -1571,15 +1568,15 @@ void t_java_generator::generate_java_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << endl; + out << '\n'; generate_field_descs(out, tstruct); - out << endl; + out << '\n'; generate_scheme_map(out, tstruct); - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (bean_style_ || private_members_) { @@ -1588,10 +1585,10 @@ void t_java_generator::generate_java_struct_definition(ostream& out, generate_java_doc(out, *m_iter); indent(out) << "public "; } - out << declare_field(*m_iter, false, true) << endl; + out << declare_field(*m_iter, false, true) << '\n'; } - out << endl; + out << '\n'; if (android_style_) { generate_java_struct_parcelable(out, tstruct); @@ -1601,9 +1598,9 @@ void t_java_generator::generate_java_struct_definition(ostream& out, // isset data if (members.size() > 0) { - out << endl; + out << '\n'; - indent(out) << "// isset id assignments" << endl; + indent(out) << "// isset id assignments" << '\n'; int i = 0; int optionals = 0; @@ -1613,7 +1610,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";" - << endl; + << '\n'; i++; } } @@ -1623,22 +1620,22 @@ void t_java_generator::generate_java_struct_definition(ostream& out, case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "private " << primitiveType << " __isset_bitfield = 0;" << endl; + indent(out) << "private " << primitiveType << " __isset_bitfield = 0;" << '\n'; break; case ISSET_BITSET: indent(out) << "private java.util.BitSet __isset_bit_vector = new java.util.BitSet(" << i - << ");" << endl; + << ");" << '\n'; break; } if (optionals > 0) { - std::string output_string = "private static final _Fields optionals[] = {"; + std::string output_string = "private static final _Fields[] optionals = {"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() == t_field::T_OPTIONAL) { output_string = output_string + "_Fields." + constant_name((*m_iter)->get_name()) + ","; } } - indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << endl; + indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << '\n'; } } @@ -1647,7 +1644,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, bool all_optional_members = true; // Default constructor - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "() {" << endl; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "() {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); @@ -1660,27 +1657,27 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (!members.empty() && !all_optional_members) { // Full constructor for all fields - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << endl; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << '\n'; indent_up(); bool first = true; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << type_name((*m_iter)->get_type()) << " " << make_valid_java_identifier((*m_iter)->get_name()); } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - indent(out) << "this();" << endl; + indent(out) << "this();" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { t_type* type = get_true_type((*m_iter)->get_type()); @@ -1688,44 +1685,44 @@ void t_java_generator::generate_java_struct_definition(ostream& out, if (unsafe_binaries_) { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = " << make_valid_java_identifier((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } else { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = org.apache.thrift.TBaseHelper.copyBinary(" << make_valid_java_identifier((*m_iter)->get_name()) - << ");" << endl; + << ");" << '\n'; } } else { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = " << make_valid_java_identifier((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } generate_isset_set(out, (*m_iter), ""); } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // copy constructor - indent(out) << "/**" << endl; - indent(out) << " * Performs a deep copy on other." << endl; - indent(out) << " */" << endl; + indent(out) << "/**" << '\n'; + indent(out) << " * Performs a deep copy on other." << '\n'; + indent(out) << " */" << '\n'; indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" - << endl; + << '\n'; indent_up(); switch (needs_isset(tstruct)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "__isset_bitfield = other.__isset_bitfield;" << endl; + indent(out) << "__isset_bitfield = other.__isset_bitfield;" << '\n'; break; case ISSET_BITSET: - indent(out) << "__isset_bit_vector.clear();" << endl; - indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << endl; + indent(out) << "__isset_bit_vector.clear();" << '\n'; + indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << '\n'; break; } @@ -1736,33 +1733,33 @@ void t_java_generator::generate_java_struct_definition(ostream& out, bool can_be_null = type_can_be_null(type); if (can_be_null) { - indent(out) << "if (other." << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (other." << generate_isset_check(field) << ") {" << '\n'; indent_up(); } if (type->is_container()) { generate_deep_copy_container(out, "other", field_name, "__this__" + field_name, type); - indent(out) << "this." << make_valid_java_identifier(field_name) << " = __this__" << field_name << ";" << endl; + indent(out) << "this." << make_valid_java_identifier(field_name) << " = __this__" << field_name << ";" << '\n'; } else { indent(out) << "this." << make_valid_java_identifier(field_name) << " = "; generate_deep_copy_non_container(out, "other." + make_valid_java_identifier(field_name), field_name, type); - out << ";" << endl; + out << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // clone method, so that you can deep copy an object when you don't know its class. - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << endl; - indent(out) << " return new " << make_valid_java_identifier(tstruct->get_name()) << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << '\n'; + indent(out) << " return new " << make_valid_java_identifier(tstruct->get_name()) << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; generate_java_struct_clear(out, tstruct); @@ -1791,7 +1788,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, generate_java_scheme_lookup(out); scope_down(out); - out << endl; + out << '\n'; } /** @@ -1803,30 +1800,30 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << indent() << java_override_annotation() << endl - << indent() << "public void writeToParcel(android.os.Parcel out, int flags) {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public void writeToParcel(android.os.Parcel out, int flags) {" << '\n'; indent_up(); string bitsetPrimitiveType = ""; switch (needs_isset(tstruct, &bitsetPrimitiveType)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << endl; + indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n'; if (bitsetPrimitiveType == "byte") { - indent(out) << "out.writeByte(__isset_bitfield);" << endl; + indent(out) << "out.writeByte(__isset_bitfield);" << '\n'; } else if (bitsetPrimitiveType == "short") { - indent(out) << "out.writeInt(new Short(__isset_bitfield).intValue());" << endl; + indent(out) << "out.writeInt(new Short(__isset_bitfield).intValue());" << '\n'; } else if (bitsetPrimitiveType == "int") { - indent(out) << "out.writeInt(__isset_bitfield);" << endl; + indent(out) << "out.writeInt(__isset_bitfield);" << '\n'; } else if (bitsetPrimitiveType == "long") { - indent(out) << "out.writeLong(__isset_bitfield);" << endl; + indent(out) << "out.writeLong(__isset_bitfield);" << '\n'; } - out << endl; + out << '\n'; break; case ISSET_BITSET: - indent(out) << "//BitSet" << endl; - indent(out) << "out.writeSerializable(__isset_bit_vector);" << endl; - out << endl; + indent(out) << "//BitSet" << '\n'; + indent(out) << "out.writeSerializable(__isset_bit_vector);" << '\n'; + out << '\n'; break; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1834,54 +1831,54 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t string name = (*m_iter)->get_name(); if (t->is_struct()) { - indent(out) << "out.writeParcelable(" << name << ", flags);" << endl; + indent(out) << "out.writeParcelable(" << name << ", flags);" << '\n'; } else if (type_name(t) == "float") { - indent(out) << "out.writeFloat(" << name << ");" << endl; + indent(out) << "out.writeFloat(" << name << ");" << '\n'; } else if (t->is_enum()) { indent(out) << "out.writeInt(" << name << " != null ? " << name << ".getValue() : -1);" - << endl; + << '\n'; } else if (t->is_list()) { if (((t_list*)t)->get_elem_type()->get_true_type()->is_struct()) { - indent(out) << "out.writeTypedList(" << name << ");" << endl; + indent(out) << "out.writeTypedList(" << name << ");" << '\n'; } else { - indent(out) << "out.writeList(" << name << ");" << endl; + indent(out) << "out.writeList(" << name << ");" << '\n'; } } else if (t->is_map()) { - indent(out) << "out.writeMap(" << name << ");" << endl; + indent(out) << "out.writeMap(" << name << ");" << '\n'; } else if (t->is_base_type()) { if (t->is_binary()) { - indent(out) << "out.writeInt(" << name << "!=null ? 1 : 0);" << endl; - indent(out) << "if(" << name << " != null) { " << endl; + indent(out) << "out.writeInt(" << name << "!=null ? 1 : 0);" << '\n'; + indent(out) << "if(" << name << " != null) { " << '\n'; indent_up(); indent(out) << "out.writeByteArray(" << name << ".array(), " << name << ".position() + " << name << ".arrayOffset(), " << name << ".limit() - " << name - << ".position() );" << endl; + << ".position() );" << '\n'; scope_down(out); } else { switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_I16: - indent(out) << "out.writeInt(new Short(" << name << ").intValue());" << endl; + indent(out) << "out.writeInt(new Short(" << name << ").intValue());" << '\n'; break; case t_base_type::TYPE_UUID: - indent(out) << "out.writeUuid(" << name << ");" << endl; + indent(out) << "out.writeUuid(" << name << ");" << '\n'; break; case t_base_type::TYPE_I32: - indent(out) << "out.writeInt(" << name << ");" << endl; + indent(out) << "out.writeInt(" << name << ");" << '\n'; break; case t_base_type::TYPE_I64: - indent(out) << "out.writeLong(" << name << ");" << endl; + indent(out) << "out.writeLong(" << name << ");" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "out.writeInt(" << name << " ? 1 : 0);" << endl; + indent(out) << "out.writeInt(" << name << " ? 1 : 0);" << '\n'; break; case t_base_type::TYPE_I8: - indent(out) << "out.writeByte(" << name << ");" << endl; + indent(out) << "out.writeByte(" << name << ");" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "out.writeDouble(" << name << ");" << endl; + indent(out) << "out.writeDouble(" << name << ");" << '\n'; break; case t_base_type::TYPE_STRING: - indent(out) << "out.writeString(" << name << ");" << endl; + indent(out) << "out.writeString(" << name << ");" << '\n'; break; case t_base_type::TYPE_VOID: break; @@ -1892,38 +1889,38 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t } } scope_down(out); - out << endl; + out << '\n'; - out << indent() << java_override_annotation() << endl - << indent() << "public int describeContents() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public int describeContents() {" << '\n'; indent_up(); - out << indent() << "return 0;" << endl; + out << indent() << "return 0;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - indent(out) << "public " << tname << "(android.os.Parcel in) {" << endl; + indent(out) << "public " << tname << "(android.os.Parcel in) {" << '\n'; indent_up(); // read in the required bitfield switch (needs_isset(tstruct, &bitsetPrimitiveType)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << endl; + indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n'; if (bitsetPrimitiveType == "byte") { - indent(out) << "__isset_bitfield = in.readByte();" << endl; + indent(out) << "__isset_bitfield = in.readByte();" << '\n'; } else if (bitsetPrimitiveType == "short") { - indent(out) << "__isset_bitfield = (short) in.readInt();" << endl; + indent(out) << "__isset_bitfield = (short) in.readInt();" << '\n'; } else if (bitsetPrimitiveType == "int") { - indent(out) << "__isset_bitfield = in.readInt();" << endl; + indent(out) << "__isset_bitfield = in.readInt();" << '\n'; } else if (bitsetPrimitiveType == "long") { - indent(out) << "__isset_bitfield = in.readLong();" << endl; + indent(out) << "__isset_bitfield = in.readLong();" << '\n'; } - out << endl; + out << '\n'; break; case ISSET_BITSET: - indent(out) << "//BitSet" << endl; - indent(out) << "__isset_bit_vector = (java.util.BitSet) in.readSerializable();" << endl; - out << endl; + indent(out) << "//BitSet" << '\n'; + indent(out) << "__isset_bit_vector = (java.util.BitSet) in.readSerializable();" << '\n'; + out << '\n'; break; } // read all the fields @@ -1934,57 +1931,57 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t if (t->is_struct()) { indent(out) << prefix << "= in.readParcelable(" << tname << ".class.getClassLoader());" - << endl; + << '\n'; } else if (t->is_enum()) { - indent(out) << prefix << " = " << type_name(t) << ".findByValue(in.readInt());" << endl; + indent(out) << prefix << " = " << type_name(t) << ".findByValue(in.readInt());" << '\n'; } else if (t->is_list()) { t_list* list = (t_list*)t; - indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << endl; + indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n'; if (list->get_elem_type()->get_true_type()->is_struct()) { indent(out) << "in.readTypedList(" << prefix << ", " << type_name(list->get_elem_type()) - << ".CREATOR);" << endl; + << ".CREATOR);" << '\n'; } else { indent(out) << "in.readList(" << prefix << ", " << tname << ".class.getClassLoader());" - << endl; + << '\n'; } } else if (t->is_map()) { - indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << endl; + indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n'; indent(out) << " in.readMap(" << prefix << ", " << tname << ".class.getClassLoader());" - << endl; + << '\n'; } else if (type_name(t) == "float") { - indent(out) << prefix << " = in.readFloat();" << endl; + indent(out) << prefix << " = in.readFloat();" << '\n'; } else if (t->is_base_type()) { t_base_type* bt = (t_base_type*)t; if (bt->is_binary()) { - indent(out) << "if(in.readInt()==1) {" << endl; + indent(out) << "if(in.readInt()==1) {" << '\n'; indent_up(); - indent(out) << prefix << " = java.nio.ByteBuffer.wrap(in.createByteArray());" << endl; + indent(out) << prefix << " = java.nio.ByteBuffer.wrap(in.createByteArray());" << '\n'; scope_down(out); } else { switch (bt->get_base()) { case t_base_type::TYPE_I8: - indent(out) << prefix << " = in.readByte();" << endl; + indent(out) << prefix << " = in.readByte();" << '\n'; break; case t_base_type::TYPE_I16: - indent(out) << prefix << " = (short) in.readInt();" << endl; + indent(out) << prefix << " = (short) in.readInt();" << '\n'; break; case t_base_type::TYPE_I32: - indent(out) << prefix << " = in.readInt();" << endl; + indent(out) << prefix << " = in.readInt();" << '\n'; break; case t_base_type::TYPE_I64: - indent(out) << prefix << " = in.readLong();" << endl; + indent(out) << prefix << " = in.readLong();" << '\n'; break; case t_base_type::TYPE_UUID: - indent(out) << prefix << " = in.readUuid();" << endl; + indent(out) << prefix << " = in.readUuid();" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << prefix << " = (in.readInt()==1);" << endl; + indent(out) << prefix << " = (in.readInt()==1);" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << prefix << " = in.readDouble();" << endl; + indent(out) << prefix << " = in.readDouble();" << '\n'; break; case t_base_type::TYPE_STRING: - indent(out) << prefix << "= in.readString();" << endl; + indent(out) << prefix << "= in.readString();" << '\n'; break; case t_base_type::TYPE_VOID: break; @@ -1996,29 +1993,29 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t } scope_down(out); - out << endl; + out << '\n'; indent(out) << "public static final android.os.Parcelable.Creator<" << tname - << "> CREATOR = new android.os.Parcelable.Creator<" << tname << ">() {" << endl; + << "> CREATOR = new android.os.Parcelable.Creator<" << tname << ">() {" << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl - << indent() << "public " << tname << "[] newArray(int size) {" << endl; + indent(out) << java_override_annotation() << '\n' + << indent() << "public " << tname << "[] newArray(int size) {" << '\n'; indent_up(); - indent(out) << "return new " << tname << "[size];" << endl; + indent(out) << "return new " << tname << "[size];" << '\n'; scope_down(out); - out << endl; + out << '\n'; - indent(out) << java_override_annotation() << endl + indent(out) << java_override_annotation() << '\n' << indent() << "public " << tname << " createFromParcel(android.os.Parcel in) {" - << endl; + << '\n'; indent_up(); - indent(out) << "return new " << tname << "(in);" << endl; + indent(out) << "return new " << tname << "(in);" << '\n'; scope_down(out); indent_down(); - indent(out) << "};" << endl; - out << endl; + indent(out) << "};" << '\n'; + out << '\n'; } /** @@ -2027,26 +2024,26 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) { - out << indent() << java_override_annotation() << endl - << indent() << "public boolean equals(java.lang.Object that) {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public boolean equals(java.lang.Object that) {" << '\n'; indent_up(); - out << indent() << "if (that instanceof " << make_valid_java_identifier(tstruct->get_name()) << ")" << endl - << indent() << " return this.equals((" << make_valid_java_identifier(tstruct->get_name()) << ")that);" << endl - << indent() << "return false;" << endl; + out << indent() << "if (that instanceof " << make_valid_java_identifier(tstruct->get_name()) << ")" << '\n' + << indent() << " return this.equals((" << make_valid_java_identifier(tstruct->get_name()) << ")that);" << '\n' + << indent() << "return false;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " that) {" << endl; + out << indent() << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl - << indent() << " return false;" << endl - << indent() << "if (this == that)" << endl - << indent() << " return true;" << endl; + out << indent() << "if (that == null)" << '\n' + << indent() << " return false;" << '\n' + << indent() << "if (this == that)" << '\n' + << indent() << " return true;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); // Most existing Thrift code does not use isset or optional/required, @@ -2064,14 +2061,14 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst that_present += " && that." + generate_isset_check(*m_iter); } - out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << endl - << indent() << "boolean that_present_" << name << " = " << that_present << ";" << endl + out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << '\n' + << indent() << "boolean that_present_" << name << " = " << that_present << ";" << '\n' << indent() << "if (" - << "this_present_" << name << " || that_present_" << name << ") {" << endl; + << "this_present_" << name << " || that_present_" << name << ") {" << '\n'; indent_up(); out << indent() << "if (!(" - << "this_present_" << name << " && that_present_" << name << "))" << endl - << indent() << " return false;" << endl; + << "this_present_" << name << " && that_present_" << name << "))" << '\n' + << indent() << " return false;" << '\n'; if (t->is_binary()) { unequal = "!this." + make_valid_java_identifier(name) + ".equals(that." + make_valid_java_identifier(name) + ")"; @@ -2081,25 +2078,25 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst unequal = "this." + make_valid_java_identifier(name) + " != that." + make_valid_java_identifier(name); } - out << indent() << "if (" << unequal << ")" << endl << indent() << " return false;" << endl; + out << indent() << "if (" << unequal << ")" << '\n' << indent() << " return false;" << '\n'; scope_down(out); } - out << endl; - indent(out) << "return true;" << endl; + out << '\n'; + indent(out) << "return true;" << '\n'; scope_down(out); - out << endl; + out << '\n'; const int MUL = 8191; // HashCode multiplier const int B_YES = 131071; const int B_NO = 524287; - out << indent() << java_override_annotation() << endl - << indent() << "public int hashCode() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public int hashCode() {" << '\n'; indent_up(); - indent(out) << "int hashCode = 1;" << endl; + indent(out) << "int hashCode = 1;" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL; @@ -2108,37 +2105,37 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst if (is_optional || can_be_null) { indent(out) << "hashCode = hashCode * " << MUL << " + ((" << generate_isset_check(*m_iter) - << ") ? " << B_YES << " : " << B_NO << ");" << endl; + << ") ? " << B_YES << " : " << B_NO << ");" << '\n'; } if (is_optional || can_be_null) { - indent(out) << "if (" + generate_isset_check(*m_iter) + ")" << endl; + indent(out) << "if (" + generate_isset_check(*m_iter) + ")" << '\n'; indent_up(); } if (t->is_enum()) { - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".getValue();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".getValue();" << '\n'; } else if (t->is_base_type()) { switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_STRING: case t_base_type::TYPE_UUID: - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << '\n'; break; case t_base_type::TYPE_BOOL: indent(out) << "hashCode = hashCode * " << MUL << " + ((" << name << ") ? " << B_YES - << " : " << B_NO << ");" << endl; + << " : " << B_NO << ");" << '\n'; break; case t_base_type::TYPE_I8: - indent(out) << "hashCode = hashCode * " << MUL << " + (int) (" << name << ");" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + (int) (" << name << ");" << '\n'; break; case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ";" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ";" << '\n'; break; case t_base_type::TYPE_I64: case t_base_type::TYPE_DOUBLE: indent(out) << "hashCode = hashCode * " << MUL - << " + org.apache.thrift.TBaseHelper.hashCode(" << name << ");" << endl; + << " + org.apache.thrift.TBaseHelper.hashCode(" << name << ");" << '\n'; break; case t_base_type::TYPE_VOID: throw std::logic_error("compiler error: a struct field cannot be void"); @@ -2147,7 +2144,7 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst + t_base_type::t_base_name(((t_base_type*)t)->get_base())); } } else { - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << '\n'; } if (is_optional || can_be_null) { @@ -2155,49 +2152,49 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst } } - out << endl; - indent(out) << "return hashCode;" << endl; + out << '\n'; + indent(out) << "return hashCode;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent_up(); - indent(out) << "if (!getClass().equals(other.getClass())) {" << endl; - indent(out) << " return getClass().getName().compareTo(other.getClass().getName());" << endl; - indent(out) << "}" << endl; - out << endl; + indent(out) << "if (!getClass().equals(other.getClass())) {" << '\n'; + indent(out) << " return getClass().getName().compareTo(other.getClass().getName());" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << "int lastComparison = 0;" << endl; - out << endl; + indent(out) << "int lastComparison = 0;" << '\n'; + out << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = *m_iter; indent(out) << "lastComparison = java.lang.Boolean.compare(" << generate_isset_check(field) - << ", other." << generate_isset_check(field) << ");" << endl; - indent(out) << "if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; + << ", other." << generate_isset_check(field) << ");" << '\n'; + indent(out) << "if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "if (" << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(field) << ") {" << '\n'; indent(out) << " lastComparison = org.apache.thrift.TBaseHelper.compareTo(this." << make_valid_java_identifier(field->get_name()) - << ", other." << make_valid_java_identifier(field->get_name()) << ");" << endl; - indent(out) << " if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << ", other." << make_valid_java_identifier(field->get_name()) << ");" << '\n'; + indent(out) << " if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2206,63 +2203,63 @@ void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* t * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_reader(ostream& out, t_struct* /*tstruct*/) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(iprot).read(iprot, this);" << endl; + indent(out) << "scheme(iprot).read(iprot, this);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // generates java method to perform various checks // (e.g. check that all required fields are set) void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public void validate() throws org.apache.thrift.TException {" << endl; + indent(out) << "public void validate() throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if (bean_style_) { - out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << endl + out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" - << (*f_iter)->get_name() << "' is unset! Struct:\" + toString());" << endl - << indent() << "}" << endl - << endl; + << (*f_iter)->get_name() << "' is unset! Struct:\" + toString());" << '\n' + << indent() << "}" << '\n' + << '\n'; } else { if (type_can_be_null((*f_iter)->get_type())) { - indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << endl; + indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << '\n'; indent(out) << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" - << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << endl; - indent(out) << "}" << endl; + << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << '\n'; + indent(out) << "}" << '\n'; } else { indent(out) << "// alas, we cannot check '" << (*f_iter)->get_name() << "' because it's a primitive and you chose the non-beans generator." - << endl; + << '\n'; } } } } - out << indent() << "// check for sub-struct validity" << endl; + out << indent() << "// check for sub-struct validity" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_type* type = get_true_type((*f_iter)->get_type()); if (type->is_struct() && !((t_struct*)type)->is_union()) { - out << indent() << "if (" << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << endl; - out << indent() << " " << make_valid_java_identifier((*f_iter)->get_name()) << ".validate();" << endl; - out << indent() << "}" << endl; + out << indent() << "if (" << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << '\n'; + out << indent() << " " << make_valid_java_identifier((*f_iter)->get_name()) << ".validate();" << '\n'; + out << indent() << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2271,15 +2268,15 @@ void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_writer(ostream& out, t_struct* /*tstruct*/) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(oprot).write(oprot, this);" << endl; + indent(out) << "scheme(oprot).write(oprot, this);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2294,30 +2291,30 @@ void t_java_generator::generate_java_struct_result_writer(ostream& out, t_struct (void)tstruct; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(oprot).write(oprot, this);" << endl; + indent(out) << "scheme(oprot).write(oprot, this);" << '\n'; indent_down(); - indent(out) << " }" << endl << endl; + indent(out) << " }" << '\n' << '\n'; } void t_java_generator::generate_java_struct_field_by_id(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_nullable_annotation() << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public _Fields fieldForId(int fieldId) {" << endl; - indent(out) << " return _Fields.findByThriftId(fieldId);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public _Fields fieldForId(int fieldId) {" << '\n'; + indent(out) << " return _Fields.findByThriftId(fieldId);" << '\n'; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_reflection_getters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "return " << (type->is_bool() ? "is" : "get") << cap_name << "();" << endl << endl; + indent(out) << "return " << (type->is_bool() ? "is" : "get") << cap_name << "();" << '\n' << '\n'; indent_down(); } @@ -2326,24 +2323,24 @@ void t_java_generator::generate_reflection_setters(ostringstream& out, string field_name, string cap_name) { const bool is_binary = type->is_binary(); - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; if (is_binary) { indent_up(); - indent(out) << "if (value instanceof byte[]) {" << endl; - indent(out) << " set" << cap_name << "((byte[])value);" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (value instanceof byte[]) {" << '\n'; + indent(out) << " set" << cap_name << "((byte[])value);" << '\n'; + indent(out) << "} else {" << '\n'; } - indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << endl; + indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << '\n'; if (is_binary) { - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "}" << endl; - indent(out) << "break;" << endl << endl; + indent(out) << "}" << '\n'; + indent(out) << "break;" << '\n' << '\n'; indent_down(); } @@ -2370,25 +2367,25 @@ void t_java_generator::generate_generic_field_getters_setters(std::ostream& out, // create the setter - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void setFieldValue(_Fields field, " << java_nullable_annotation() - << " java.lang.Object value) {" << endl; - indent(out) << " switch (field) {" << endl; + << " java.lang.Object value) {" << '\n'; + indent(out) << " switch (field) {" << '\n'; out << setter_stream.str(); - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; // create the getter - indent(out) << java_nullable_annotation() << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public java.lang.Object getFieldValue(_Fields field) {" << endl; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public java.lang.Object getFieldValue(_Fields field) {" << '\n'; indent_up(); - indent(out) << "switch (field) {" << endl; + indent(out) << "switch (field) {" << '\n'; out << getter_stream.str(); - indent(out) << "}" << endl; - indent(out) << "throw new java.lang.IllegalStateException();" << endl; + indent(out) << "}" << '\n'; + indent(out) << "throw new java.lang.IllegalStateException();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Creates a generic isSet method that takes the field number as argument @@ -2399,28 +2396,28 @@ void t_java_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "/** Returns true if field corresponding to fieldID is set (has been assigned a " "value) and false otherwise */" - << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public boolean isSet(_Fields field) {" << endl; + << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public boolean isSet(_Fields field) {" << '\n'; indent_up(); - indent(out) << "if (field == null) {" << endl; - indent(out) << " throw new java.lang.IllegalArgumentException();" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "if (field == null) {" << '\n'; + indent(out) << " throw new java.lang.IllegalArgumentException();" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "switch (field) {" << endl; + indent(out) << "switch (field) {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "}" << endl; - indent(out) << "throw new java.lang.IllegalStateException();" << endl; + indent(out) << "}" << '\n'; + indent(out) << "throw new java.lang.IllegalStateException();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2445,7 +2442,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts // Method to return the size of the collection if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2454,20 +2451,20 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts indent(out) << "public " << thrift_option_class << " get" << cap_name; } - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2475,24 +2472,24 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ".size());" << endl; + out << field_name << ".size());" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public int get" << cap_name; - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? 0 : " - << "this." << field_name << ".size();" << endl; + << "this." << field_name << ".size();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2507,7 +2504,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts // Iterator getter for sets and lists if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2518,20 +2515,20 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts out << "java.util.Iterator<" << type_name(element_type, true, false) << ">> get" << cap_name; - out << get_cap_name("iterator() {") << endl; + out << get_cap_name("iterator() {") << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2539,104 +2536,104 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ".iterator());" << endl; + out << field_name << ".iterator());" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << java_nullable_annotation() << endl; + indent(out) << java_nullable_annotation() << '\n'; indent(out) << "public java.util.Iterator<" << type_name(element_type, true, false) << "> get" << cap_name; - out << get_cap_name("iterator() {") << endl; + out << get_cap_name("iterator() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? null : " - << "this." << field_name << ".iterator();" << endl; + << "this." << field_name << ".iterator();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Add to set or list, create if the set/list is null if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void add" << get_cap_name("to"); - out << cap_name << "(" << type_name(element_type) << " elem) {" << endl; + out << cap_name << "(" << type_name(element_type) << " elem) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name; if (is_enum_set(type)) { out << " = " << type_name(type, false, true, true) << ".noneOf(" - << inner_enum_type_name(type) << ");" << endl; + << inner_enum_type_name(type) << ");" << '\n'; } else { - out << " = new " << type_name(type, false, true) << "();" << endl; + out << " = new " << type_name(type, false, true) << "();" << '\n'; } indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".add(elem);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".add(elem);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else if (type->is_map()) { // Put to map t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void put" << get_cap_name("to"); out << cap_name << "(" << type_name(key_type) << " key, " << type_name(val_type) << " val) {" - << endl; + << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); std::string constructor_args; if (is_enum_map(type)) { constructor_args = inner_enum_type_name(type); } indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "(" - << constructor_args << ");" << endl; + << constructor_args << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".put(key, val);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".put(key, val);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Simple getter generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public byte[] get" << cap_name << "() {" << endl; + indent(out) << "public byte[] get" << cap_name << "() {" << '\n'; indent(out) << " set" << cap_name << "(org.apache.thrift.TBaseHelper.rightSize(" - << field_name << "));" << endl; + << field_name << "));" << '\n'; indent(out) << " return " << field_name << " == null ? null : " << field_name << ".array();" - << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public java.nio.ByteBuffer buffer" << get_cap_name("for") << cap_name - << "() {" << endl; + << "() {" << '\n'; if (unsafe_binaries_) { - indent(out) << " return " << field_name << ";" << endl; + indent(out) << " return " << field_name << ";" << '\n'; } else { indent(out) << " return org.apache.thrift.TBaseHelper.copyBinary(" << field_name << ");" - << endl; + << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2650,10 +2647,10 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "if (this.isSet" << cap_name << "()) {" << endl; + indent(out) << "if (this.isSet" << cap_name << "()) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2661,28 +2658,28 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ");" << endl; + out << field_name << ");" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (type_can_be_null(type)) { - indent(out) << java_nullable_annotation() << endl; + indent(out) << java_nullable_annotation() << '\n'; } indent(out) << "public " << type_name(type); if (type->is_base_type() && ((t_base_type*)type)->get_base() == t_base_type::TYPE_BOOL) { @@ -2690,11 +2687,11 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "return this." << make_valid_java_identifier(field_name) << ";" << endl; + indent(out) << "return this." << make_valid_java_identifier(field_name) << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2702,7 +2699,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public "; if (bean_style_) { @@ -2710,23 +2707,23 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << type_name(tstruct); } - out << " set" << cap_name << "(byte[] " << make_valid_java_identifier(field_name) << ") {" << endl; + out << " set" << cap_name << "(byte[] " << make_valid_java_identifier(field_name) << ") {" << '\n'; indent(out) << " this." << make_valid_java_identifier(field_name) << " = " << make_valid_java_identifier(field_name) << " == null ? (java.nio.ByteBuffer)null"; if (unsafe_binaries_) { - indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ");" << endl; + indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ");" << '\n'; } else { - indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ".clone());" << endl; + indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ".clone());" << '\n'; } if (!bean_style_) { - indent(out) << " return this;" << endl; + indent(out) << " return this;" << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public "; if (bean_style_) { @@ -2737,7 +2734,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts out << " set" << cap_name << "(" << (type_can_be_null(type) ? (java_nullable_annotation() + " ") : "") << type_name(type) - << " " << make_valid_java_identifier(field_name) << ") {" << endl; + << " " << make_valid_java_identifier(field_name) << ") {" << '\n'; indent_up(); indent(out) << "this." << make_valid_java_identifier(field_name) << " = "; if (type->is_binary() && !unsafe_binaries_) { @@ -2745,70 +2742,70 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << make_valid_java_identifier(field_name); } - out << ";" << endl; + out << ";" << '\n'; generate_isset_set(out, field, ""); if (!bean_style_) { - indent(out) << "return this;" << endl; + indent(out) << "return this;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public void unset" << cap_name << "() {" << endl; + indent(out) << "public void unset" << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << make_valid_java_identifier(field_name) << " = null;" << endl; + indent(out) << "this." << make_valid_java_identifier(field_name) << " = null;" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "__isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, " - << isset_field_id(field) << ");" << endl; + << isset_field_id(field) << ");" << '\n'; } else { - indent(out) << "__isset_bit_vector.clear(" << isset_field_id(field) << ");" << endl; + indent(out) << "__isset_bit_vector.clear(" << isset_field_id(field) << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "/** Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise */" << endl; + << " is set (has been assigned a value) and false otherwise */" << '\n'; if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << endl; + indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << make_valid_java_identifier(field_name) << " != null;" << endl; + indent(out) << "return this." << make_valid_java_identifier(field_name) << " != null;" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, " - << isset_field_id(field) << ");" << endl; + << isset_field_id(field) << ");" << '\n'; } else { - indent(out) << "return __isset_bit_vector.get(" << isset_field_id(field) << ");" << endl; + indent(out) << "return __isset_bit_vector.get(" << isset_field_id(field) << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << cap_name << get_cap_name("isSet") << "(boolean value) {" - << endl; + << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "if (!value) {" << endl; - indent(out) << " this." << make_valid_java_identifier(field_name) << " = null;" << endl; - indent(out) << "}" << endl; + indent(out) << "if (!value) {" << '\n'; + indent(out) << " this." << make_valid_java_identifier(field_name) << " = null;" << '\n'; + indent(out) << "}" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "__isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, " - << isset_field_id(field) << ", value);" << endl; + << isset_field_id(field) << ", value);" << '\n'; } else { - indent(out) << "__isset_bit_vector.set(" << isset_field_id(field) << ", value);" << endl; + indent(out) << "__isset_bit_vector.set(" << isset_field_id(field) << ", value);" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2818,13 +2815,13 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) { - out << indent() << java_override_annotation() << endl - << indent() << "public java.lang.String toString() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public java.lang.String toString() {" << '\n'; indent_up(); out << indent() << "java.lang.StringBuilder sb = new java.lang.StringBuilder(\"" - << tstruct->get_name() << "(\");" << endl; - out << indent() << "boolean first = true;" << endl << endl; + << tstruct->get_name() << "(\");" << '\n'; + out << indent() << "boolean first = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -2832,55 +2829,55 @@ void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tst for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) sb.append(\", \");" << endl; + indent(out) << "if (!first) sb.append(\", \");" << '\n'; } - indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << endl; + indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << make_valid_java_identifier((*f_iter)->get_name()) << " == null) {" << endl; - indent(out) << " sb.append(\"null\");" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << make_valid_java_identifier((*f_iter)->get_name()) << " == null) {" << '\n'; + indent(out) << " sb.append(\"null\");" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (get_true_type(field->get_type())->is_binary()) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else if ((field->get_type()->is_set()) && (get_true_type(((t_set*)field->get_type())->get_elem_type())->is_binary())) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else if ((field->get_type()->is_list()) && (get_true_type(((t_list*)field->get_type())->get_elem_type())->is_binary())) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else { - indent(out) << "sb.append(this." << make_valid_java_identifier((*f_iter)->get_name()) << ");" << endl; + indent(out) << "sb.append(this." << make_valid_java_identifier((*f_iter)->get_name()) << ");" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "sb.append(\")\");" << endl << indent() << "return sb.toString();" << endl; + out << indent() << "sb.append(\")\");" << '\n' << indent() << "return sb.toString();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2896,14 +2893,14 @@ void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstru // Static Map with fieldID -> org.apache.thrift.meta_data.FieldMetaData mappings indent(out) << "public static final java.util.Map<_Fields, " "org.apache.thrift.meta_data.FieldMetaData> metaDataMap;" - << endl; - indent(out) << "static {" << endl; + << '\n'; + indent(out) << "static {" << '\n'; indent_up(); indent(out) << "java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new " "java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);" - << endl; + << '\n'; // Populate map for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -2928,15 +2925,15 @@ void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstru if (annotations_as_metadata_) { generate_metadata_for_field_annotations(out, field); } - out << "));" << endl; + out << "));" << '\n'; } - indent(out) << "metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);" << endl; + indent(out) << "metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);" << '\n'; indent(out) << "org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(" - << type_name(tstruct) << ".class, metaDataMap);" << endl; + << type_name(tstruct) << ".class, metaDataMap);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -3000,22 +2997,31 @@ std::string t_java_generator::get_java_type_string(t_type* type) { } void t_java_generator::generate_metadata_for_field_annotations(std::ostream& out, t_field* field) { - if (field->annotations_.size() == 0) { + if (field->annotations_.size() == 0 && field->get_type()->annotations_.size() == 0) { return; } - out << ", " << endl; + out << ", " << '\n'; indent_up(); indent_up(); indent(out) << "java.util.stream.Stream.>builder()" - << endl; + << '\n'; indent_up(); indent_up(); for (auto& annotation : field->annotations_) { indent(out) << ".add(new java.util.AbstractMap.SimpleImmutableEntry<>(\"" + annotation.first + "\", \"" + annotation.second.back() + "\"))" - << endl; + << '\n'; + } + for (auto& annotation : field->get_type()->annotations_) { + // field annotations have higher priority than type annotations + if (field->annotations_.find(annotation.first) != field->annotations_.end()) { + continue; + } + indent(out) << ".add(new java.util.AbstractMap.SimpleImmutableEntry<>(\"" + annotation.first + + "\", \"" + annotation.second.back() + "\"))" + << '\n'; } indent(out) << ".build().collect(java.util.stream.Collectors.toMap(java.util.Map.Entry::getKey, " "java.util.Map.Entry::getValue))"; @@ -3028,7 +3034,7 @@ void t_java_generator::generate_metadata_for_field_annotations(std::ostream& out void t_java_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { t_type* ttype = get_true_type(type); - out << endl; + out << '\n'; indent_up(); indent_up(); if (ttype->is_struct() || ttype->is_xception()) { @@ -3093,7 +3099,7 @@ void t_java_generator::generate_service(t_service* tservice) { generate_javax_generated_annotation(f_service_); } f_service_ << java_suppressions(); - f_service_ << "public class " << make_valid_java_identifier(service_name_) << " {" << endl << endl; + f_service_ << "public class " << make_valid_java_identifier(service_name_) << " {" << '\n' << '\n'; indent_up(); // Generate the three main parts of the service @@ -3112,7 +3118,7 @@ void t_java_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; f_service_.close(); } @@ -3130,16 +3136,16 @@ void t_java_generator::generate_service_interface(t_service* tservice) { } generate_java_doc(f_service_, tservice); - f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface Iface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_service_, *f_iter); - indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_service_async_interface(t_service* tservice) { @@ -3150,17 +3156,17 @@ void t_java_generator::generate_service_async_interface(t_service* tservice) { extends_iface = " extends " + extends + ".AsyncIface"; } - f_service_ << indent() << "public interface AsyncIface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface AsyncIface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "public " << function_signature_async(*f_iter, true) - << " throws org.apache.thrift.TException;" << endl - << endl; + << " throws org.apache.thrift.TException;" << '\n' + << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_service_future_interface(t_service* tservice) { @@ -3171,15 +3177,15 @@ void t_java_generator::generate_service_future_interface(t_service* tservice) { extends_iface = " extends " + extends + " .FutureIface"; } - f_service_ << indent() << "public interface FutureIface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface FutureIface" << extends_iface << " {" << '\n' << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { indent(f_service_) << "public " << function_signature_future(tfunc) - << " throws org.apache.thrift.TException;" << endl - << endl; + << " throws org.apache.thrift.TException;" << '\n' + << '\n'; } scope_down(f_service_); - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; } /** @@ -3209,43 +3215,43 @@ void t_java_generator::generate_service_client(t_service* tservice) { } indent(f_service_) << "public static class Client extends " << extends_client - << " implements Iface {" << endl; + << " implements Iface {" << '\n'; indent_up(); indent(f_service_) << "public static class Factory implements org.apache.thrift.TServiceClientFactory {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "public Factory() {}" << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "public Factory() {}" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public Client getClient(org.apache.thrift.protocol.TProtocol prot) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "return new Client(prot);" << endl; + indent(f_service_) << "return new Client(prot);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "}" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public Client getClient(org.apache.thrift.protocol.TProtocol iprot, " "org.apache.thrift.protocol.TProtocol oprot) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "return new Client(iprot, oprot);" << endl; + indent(f_service_) << "return new Client(iprot, oprot);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol prot)" << endl; + indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol prot)" << '\n'; scope_up(f_service_); - indent(f_service_) << "super(prot, prot);" << endl; + indent(f_service_) << "super(prot, prot);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol iprot, " "org.apache.thrift.protocol.TProtocol oprot) {" - << endl; - indent(f_service_) << " super(iprot, oprot);" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " super(iprot, oprot);" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -3260,8 +3266,8 @@ void t_java_generator::generate_service_client(t_service* tservice) { } // Open function - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << function_signature(*f_iter) << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << function_signature(*f_iter) << '\n'; scope_up(f_service_); indent(f_service_) << "send" << sep << javaname << "("; @@ -3280,17 +3286,17 @@ void t_java_generator::generate_service_client(t_service* tservice) { } f_service_ << make_valid_java_identifier((*fld_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv" << sep << javaname << "();" << endl; + f_service_ << "recv" << sep << javaname << "();" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; t_function send_function(g_type_void, string("send") + sep + javaname, (*f_iter)->get_arglist()); @@ -3298,22 +3304,22 @@ void t_java_generator::generate_service_client(t_service* tservice) { string argsname = (*f_iter)->get_name() + "_args"; // Open function - indent(f_service_) << "public " << function_signature(&send_function) << endl; + indent(f_service_) << "public " << function_signature(&send_function) << '\n'; scope_up(f_service_); // Serialize the request - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << endl; + << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << '\n'; } const string sendBaseName = (*f_iter)->is_oneway() ? "sendBaseOneway" : "sendBase"; - indent(f_service_) << sendBaseName << "(\"" << funname << "\", args);" << endl; + indent(f_service_) << sendBaseName << "(\"" << funname << "\", args);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (!(*f_iter)->is_oneway()) { string resultname = (*f_iter)->get_name() + "_result"; @@ -3322,47 +3328,47 @@ void t_java_generator::generate_service_client(t_service* tservice) { t_function recv_function((*f_iter)->get_returntype(), string("recv") + sep + javaname, &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << "public " << function_signature(&recv_function) << endl; + indent(f_service_) << "public " << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << resultname << " result = new " << resultname << "();" << endl - << indent() << "receiveBase(result, \"" << funname << "\");" << endl; + f_service_ << indent() << resultname << " result = new " << resultname << "();" << '\n' + << indent() << "receiveBase(result, \"" << funname << "\");" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << endl - << indent() << " return result.success;" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << '\n' + << indent() << " return result.success;" << '\n' + << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (result." << make_valid_java_identifier((*x_iter)->get_name()) << " != null) {" << endl - << indent() << " throw result." << make_valid_java_identifier((*x_iter)->get_name()) << ";" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << make_valid_java_identifier((*x_iter)->get_name()) << " != null) {" << '\n' + << indent() << " throw result." << make_valid_java_identifier((*x_iter)->get_name()) << ";" << '\n' + << indent() << "}" << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "throw new " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } void t_java_generator::generate_service_future_client(t_service* tservice) { @@ -3373,13 +3379,13 @@ void t_java_generator::generate_service_future_client(t_service* tservice) { static string adapter_class = "org.apache.thrift.async.AsyncMethodFutureAdapter"; indent(f_service_) << "public static class FutureClient " << extends_client - << "implements FutureIface {" << endl; + << "implements FutureIface {" << '\n'; indent_up(); - indent(f_service_) << "public FutureClient(AsyncIface delegate) {" << endl; + indent(f_service_) << "public FutureClient(AsyncIface delegate) {" << '\n'; indent_up(); - indent(f_service_) << "this.delegate = delegate;" << endl; + indent(f_service_) << "this.delegate = delegate;" << '\n'; scope_down(f_service_); - indent(f_service_) << "private final AsyncIface delegate;" << endl; + indent(f_service_) << "private final AsyncIface delegate;" << '\n'; for (auto tfunc : tservice->get_functions()) { string funname = tfunc->get_name(); string sep = "_"; @@ -3396,23 +3402,23 @@ void t_java_generator::generate_service_future_client(t_service* tservice) { string args_name = funname + "_args"; string result_name = funname + "_result"; - indent(f_service_) << "@Override" << endl; + indent(f_service_) << "@Override" << '\n'; indent(f_service_) << "public " << function_signature_future(tfunc) - << " throws org.apache.thrift.TException {" << endl; + << " throws org.apache.thrift.TException {" << '\n'; indent_up(); auto adapter = tmp("asyncMethodFutureAdapter"); indent(f_service_) << adapter_class << "<" << ret_type_name << "> " << adapter << " = " - << adapter_class << ".<" << ret_type_name << ">create();" << endl; + << adapter_class << ".<" << ret_type_name << ">create();" << '\n'; bool empty_args = tfunc->get_arglist()->get_members().empty(); indent(f_service_) << "delegate." << get_rpc_method_name(funname) << "(" << argument_list(tfunc->get_arglist(), false) << (empty_args ? "" : ", ") - << adapter << ");" << endl; - indent(f_service_) << "return " << adapter << ".getFuture();" << endl; + << adapter << ");" << '\n'; + indent(f_service_) << "return " << adapter << ".getFuture();" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } void t_java_generator::generate_service_async_client(t_service* tservice) { @@ -3422,41 +3428,41 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { } indent(f_service_) << "public static class AsyncClient extends " << extends_client - << " implements AsyncIface {" << endl; + << " implements AsyncIface {" << '\n'; indent_up(); // Factory method indent(f_service_) << "public static class Factory implements " "org.apache.thrift.async.TAsyncClientFactory {" - << endl; + << '\n'; indent(f_service_) << " private org.apache.thrift.async.TAsyncClientManager clientManager;" - << endl; + << '\n'; indent(f_service_) << " private org.apache.thrift.protocol.TProtocolFactory protocolFactory;" - << endl; + << '\n'; indent(f_service_) << " public Factory(org.apache.thrift.async.TAsyncClientManager " "clientManager, org.apache.thrift.protocol.TProtocolFactory " "protocolFactory) {" - << endl; - indent(f_service_) << " this.clientManager = clientManager;" << endl; - indent(f_service_) << " this.protocolFactory = protocolFactory;" << endl; - indent(f_service_) << " }" << endl; - indent(f_service_) << java_override_annotation() << endl; + << '\n'; + indent(f_service_) << " this.clientManager = clientManager;" << '\n'; + indent(f_service_) << " this.protocolFactory = protocolFactory;" << '\n'; + indent(f_service_) << " }" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << " public AsyncClient " "getAsyncClient(org.apache.thrift.transport.TNonblockingTransport " "transport) {" - << endl; + << '\n'; indent(f_service_) << " return new AsyncClient(protocolFactory, clientManager, transport);" - << endl; - indent(f_service_) << " }" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " }" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "public AsyncClient(org.apache.thrift.protocol.TProtocolFactory " "protocolFactory, org.apache.thrift.async.TAsyncClientManager " "clientManager, org.apache.thrift.transport.TNonblockingTransport " "transport) {" - << endl; - indent(f_service_) << " super(protocolFactory, clientManager, transport);" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " super(protocolFactory, clientManager, transport);" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -3479,35 +3485,35 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { string result_name = (*f_iter)->get_name() + "_result"; // Main method body - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " << function_signature_async(*f_iter, false) - << " throws org.apache.thrift.TException {" << endl; - indent(f_service_) << " checkReady();" << endl; + << " throws org.apache.thrift.TException {" << '\n'; + indent(f_service_) << " checkReady();" << '\n'; indent(f_service_) << " " << funclassname << " method_call = new " + funclassname + "(" << async_argument_list(*f_iter, arg_struct, ret_type) - << ", this, ___protocolFactory, ___transport);" << endl; - indent(f_service_) << " this.___currentMethod = method_call;" << endl; - indent(f_service_) << " ___manager.call(method_call);" << endl; - indent(f_service_) << "}" << endl; + << ", this, ___protocolFactory, ___transport);" << '\n'; + indent(f_service_) << " this.___currentMethod = method_call;" << '\n'; + indent(f_service_) << " ___manager.call(method_call);" << '\n'; + indent(f_service_) << "}" << '\n'; - f_service_ << endl; + f_service_ << '\n'; // TAsyncMethod object for this function call indent(f_service_) << "public static class " + funclassname + " extends org.apache.thrift.async.TAsyncMethodCall<" + type_name((*f_iter)->get_returntype(), true) + "> {" - << endl; + << '\n'; indent_up(); // Member variables for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << "private " + type_name((*fld_iter)->get_type()) + " " + make_valid_java_identifier((*fld_iter)->get_name()) + ";" - << endl; + << '\n'; } // NOTE since we use a new Client instance to deserialize, let's keep seqid to 0 for now - // indent(f_service_) << "private int seqid;" << endl << endl; + // indent(f_service_) << "private int seqid;" << '\n' << '\n'; // Constructor indent(f_service_) << "public " + funclassname + "(" @@ -3516,22 +3522,22 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { "org.apache.thrift.protocol.TProtocolFactory protocolFactory, " "org.apache.thrift.transport.TNonblockingTransport transport) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent(f_service_) << " super(client, protocolFactory, transport, resultHandler, " - << ((*f_iter)->is_oneway() ? "true" : "false") << ");" << endl; + << ((*f_iter)->is_oneway() ? "true" : "false") << ");" << '\n'; // Assign member variables for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << " this." + make_valid_java_identifier((*fld_iter)->get_name()) + " = " + make_valid_java_identifier((*fld_iter)->get_name()) + ";" - << endl; + << '\n'; } - indent(f_service_) << "}" << endl << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "}" << '\n' << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public void write_args(org.apache.thrift.protocol.TProtocol prot) " "throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); // Serialize request @@ -3539,68 +3545,68 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { f_service_ << indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" << funname << "\", org.apache.thrift.protocol." << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << ", 0));" - << endl - << indent() << args_name << " args = new " << args_name << "();" << endl; + << '\n' + << indent() << args_name << " args = new " << args_name << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << endl; + << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << '\n'; } - f_service_ << indent() << "args.write(prot);" << endl - << indent() << "prot.writeMessageEnd();" << endl; + f_service_ << indent() << "args.write(prot);" << '\n' + << indent() << "prot.writeMessageEnd();" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Return method - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " + type_name(ret_type, true) + " getResult() throws "; vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << type_name((*x_iter)->get_type(), false, false) + ", "; } - f_service_ << "org.apache.thrift.TException {" << endl; + f_service_ << "org.apache.thrift.TException {" << '\n'; indent_up(); f_service_ << indent() << "if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {" - << endl + << '\n' << indent() << " throw new java.lang.IllegalStateException(\"Method call not finished!\");" - << endl - << indent() << "}" << endl + << '\n' + << indent() << "}" << '\n' << indent() << "org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new " "org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());" - << endl + << '\n' << indent() << "org.apache.thrift.protocol.TProtocol prot = " "client.getProtocolFactory().getProtocol(memoryTransport);" - << endl; + << '\n'; indent(f_service_); if (ret_type->is_void()) { // NB: Includes oneways which always return void. if (!(*f_iter)->is_oneway()) { - f_service_ << "(new Client(prot)).recv" + sep + javaname + "();" << endl; + f_service_ << "(new Client(prot)).recv" + sep + javaname + "();" << '\n'; indent(f_service_); } - f_service_ << "return null;" << endl; + f_service_ << "return null;" << '\n'; } else { - f_service_ << "return (new Client(prot)).recv" + sep + javaname + "();" << endl; + f_service_ << "return (new Client(prot)).recv" + sep + javaname + "();" << '\n'; } // Close function indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; // Close class indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } // Close AsyncClient scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } /** @@ -3625,41 +3631,42 @@ void t_java_generator::generate_service_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class Processor extends " - << extends_processor << " implements org.apache.thrift.TProcessor {" << endl; + << extends_processor << " implements org.apache.thrift.TProcessor {" << '\n'; indent_up(); indent(f_service_) << "private static final org.slf4j.Logger _LOGGER = " "org.slf4j.LoggerFactory.getLogger(Processor.class.getName());" - << endl; + << '\n'; - indent(f_service_) << "public Processor(I iface) {" << endl; + indent(f_service_) << "public Processor(I iface) {" << '\n'; indent(f_service_) << " super(iface, getProcessMap(new java.util.HashMap>()));" - << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ? extends org.apache.thrift.TBase>>()));" + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "protected Processor(I iface, java.util.Map> " - "processMap) {" - << endl; - indent(f_service_) << " super(iface, getProcessMap(processMap));" << endl; - indent(f_service_) << "}" << endl << endl; - - indent(f_service_) << "private static java.util.Map> " + "org.apache.thrift.ProcessFunction> processMap) {" + << '\n'; + indent(f_service_) << " super(iface, getProcessMap(processMap));" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << "private static java.util.Map> " "getProcessMap(java.util.Map> processMap) {" - << endl; + " org.apache.thrift.TBase, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "processMap.put(\"" << (*f_iter)->get_name() << "\", new " - << make_valid_java_identifier((*f_iter)->get_name()) << "());" << endl; + << make_valid_java_identifier((*f_iter)->get_name()) << "());" << '\n'; } - indent(f_service_) << "return processMap;" << endl; + indent(f_service_) << "return processMap;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -3667,7 +3674,7 @@ void t_java_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -3692,42 +3699,42 @@ void t_java_generator::generate_service_async_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class AsyncProcessor extends " - << extends_processor << " {" << endl; + << extends_processor << " {" << '\n'; indent_up(); indent(f_service_) << "private static final org.slf4j.Logger _LOGGER = " "org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());" - << endl; + << '\n'; - indent(f_service_) << "public AsyncProcessor(I iface) {" << endl; + indent(f_service_) << "public AsyncProcessor(I iface) {" << '\n'; indent(f_service_) << " super(iface, getProcessMap(new java.util.HashMap>()));" - << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>>()));" + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "protected AsyncProcessor(I iface, java.util.Map> processMap) {" - << endl; - indent(f_service_) << " super(iface, getProcessMap(processMap));" << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; + indent(f_service_) << " super(iface, getProcessMap(processMap));" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "private static java.util.Map> getProcessMap(java.util.Map> getProcessMap(java.util.Map> processMap) {" - << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "processMap.put(\"" << (*f_iter)->get_name() << "\", new " - << make_valid_java_identifier((*f_iter)->get_name()) << "());" << endl; + << make_valid_java_identifier((*f_iter)->get_name()) << "());" << '\n'; } - indent(f_service_) << "return processMap;" << endl; + indent(f_service_) << "return processMap;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -3735,7 +3742,7 @@ void t_java_generator::generate_service_async_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -3783,91 +3790,101 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu // Open class indent(f_service_) << "public static class " << make_valid_java_identifier(tfunction->get_name()) << " extends org.apache.thrift.AsyncProcessFunction {" << endl; + << argsname << ", " << resulttype << ", " << resultname << "> {" << '\n'; indent_up(); - indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << endl; - indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << '\n'; + indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << resultname << " getEmptyResultInstance() {" << '\n'; + if (tfunction->is_oneway()) { + indent(f_service_) << " return null;" << '\n'; + } + else { + indent(f_service_) << " return new " << resultname << "();" << '\n'; + } + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << endl; - indent(f_service_) << " return new " << argsname << "();" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << '\n'; + indent(f_service_) << " return new " << argsname << "();" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public org.apache.thrift.async.AsyncMethodCallback<" << resulttype << "> getResultHandler(final " "org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, " "final int seqid) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "final org.apache.thrift.AsyncProcessFunction fcall = this;" << endl; + indent(f_service_) << "final org.apache.thrift.AsyncProcessFunction fcall = this;" << '\n'; indent(f_service_) << "return new org.apache.thrift.async.AsyncMethodCallback<" << resulttype - << ">() { " << endl; + << ">() { " << '\n'; indent_up(); - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public void onComplete(" << resulttype << " o) {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public void onComplete(" << resulttype << " o) {" << '\n'; indent_up(); if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; if (!tfunction->get_returntype()->is_void()) { - indent(f_service_) << "result.success = o;" << endl; + indent(f_service_) << "result.success = o;" << '\n'; // Set isset on success field if (!type_can_be_null(tfunction->get_returntype())) { indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent(f_service_) << " fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);" - << endl; - indent(f_service_) << "} catch (org.apache.thrift.transport.TTransportException e) {" << endl; + << '\n'; + indent(f_service_) << "} catch (org.apache.thrift.transport.TTransportException e) {" << '\n'; indent_up(); f_service_ << indent() << "_LOGGER.error(\"TTransportException writing to internal frame buffer\", e);" - << endl - << indent() << "fb.close();" << endl; + << '\n' + << indent() << "fb.close();" << '\n'; indent_down(); - indent(f_service_) << "} catch (java.lang.Exception e) {" << endl; + indent(f_service_) << "} catch (java.lang.Exception e) {" << '\n'; indent_up(); f_service_ << indent() << "_LOGGER.error(\"Exception writing to internal frame buffer\", e);" - << endl - << indent() << "onError(e);" << endl; + << '\n' + << indent() << "onError(e);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public void onError(java.lang.Exception e) {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public void onError(java.lang.Exception e) {" << '\n'; indent_up(); if (tfunction->is_oneway()) { indent(f_service_) << "if (e instanceof org.apache.thrift.transport.TTransportException) {" - << endl; + << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << endl - << indent() << "fb.close();" << endl; + f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n' + << indent() << "fb.close();" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"Exception inside oneway handler\", e);" << endl; + f_service_ << indent() << "_LOGGER.error(\"Exception inside oneway handler\", e);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;" << endl; - indent(f_service_) << "org.apache.thrift.TSerializable msg;" << endl; - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << "byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;" << '\n'; + indent(f_service_) << "org.apache.thrift.TSerializable msg;" << '\n'; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -3879,66 +3896,66 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu f_service_ << indent(); string type = type_name((*x_iter)->get_type(), false, false); string name = (*x_iter)->get_name(); - f_service_ << "if (e instanceof " << type << ") {" << endl; + f_service_ << "if (e instanceof " << type << ") {" << '\n'; indent_up(); - f_service_ << indent() << "result." << make_valid_java_identifier(name) << " = (" << type << ") e;" << endl + f_service_ << indent() << "result." << make_valid_java_identifier(name) << " = (" << type << ") e;" << '\n' << indent() << "result.set" << get_cap_name(name) << get_cap_name("isSet") - << "(true);" << endl - << indent() << "msg = result;" << endl; + << "(true);" << '\n' + << indent() << "msg = result;" << '\n'; indent_down(); indent(f_service_) << "} else "; } } else { indent(f_service_); } - f_service_ << "if (e instanceof org.apache.thrift.transport.TTransportException) {" << endl; + f_service_ << "if (e instanceof org.apache.thrift.transport.TTransportException) {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << endl - << indent() << "fb.close();" << endl - << indent() << "return;" << endl; + f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n' + << indent() << "fb.close();" << '\n' + << indent() << "return;" << '\n'; indent_down(); indent(f_service_) << "} else if (e instanceof org.apache.thrift.TApplicationException) {" - << endl; + << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TApplicationException inside handler\", e);" << endl - << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << endl - << indent() << "msg = (org.apache.thrift.TApplicationException)e;" << endl; + f_service_ << indent() << "_LOGGER.error(\"TApplicationException inside handler\", e);" << '\n' + << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n' + << indent() << "msg = (org.apache.thrift.TApplicationException)e;" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"Exception inside handler\", e);" << endl - << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << endl + f_service_ << indent() << "_LOGGER.error(\"Exception inside handler\", e);" << '\n' + << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n' << indent() << "msg = new " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.INTERNAL_ERROR, e.getMessage());" - << endl; + << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << indent() << "try {" << endl - << indent() << " fcall.sendResponse(fb,msg,msgType,seqid);" << endl - << indent() << "} catch (java.lang.Exception ex) {" << endl + f_service_ << indent() << "}" << '\n' + << indent() << "try {" << '\n' + << indent() << " fcall.sendResponse(fb,msg,msgType,seqid);" << '\n' + << indent() << "} catch (java.lang.Exception ex) {" << '\n' << indent() << " _LOGGER.error(\"Exception writing to internal frame buffer\", ex);" - << endl - << indent() << " fb.close();" << endl - << indent() << "}" << endl; + << '\n' + << indent() << " fb.close();" << '\n' + << indent() << "}" << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean isOneway() {" << endl; - indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public boolean isOneway() {" << '\n'; + indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public void start(I iface, " << argsname << " args, org.apache.thrift.async.AsyncMethodCallback<" << resulttype - << "> resultHandler) throws org.apache.thrift.TException {" << endl; + << "> resultHandler) throws org.apache.thrift.TException {" << '\n'; indent_up(); // Generate the function call @@ -3960,17 +3977,17 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu if (!first) f_service_ << ","; f_service_ << "resultHandler"; - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); indent(f_service_) << "}"; // Close function - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -3989,35 +4006,45 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function // Open class indent(f_service_) << "public static class " << make_valid_java_identifier(tfunction->get_name()) << " extends org.apache.thrift.ProcessFunction {" << endl; + << argsname << ", " << resultname << "> {" << '\n'; indent_up(); - indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << endl; - indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << '\n'; + indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << endl; - indent(f_service_) << " return new " << argsname << "();" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << '\n'; + indent(f_service_) << " return new " << argsname << "();" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean isOneway() {" << endl; - indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public boolean isOneway() {" << '\n'; + indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean rethrowUnhandledExceptions() {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "protected boolean rethrowUnhandledExceptions() {" << '\n'; indent(f_service_) << " return " << ((rethrow_unhandled_exceptions_) ? "true" : "false") << ";" - << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << resultname << " getEmptyResultInstance() {" << '\n'; + if (tfunction->is_oneway()) { + indent(f_service_) << " return null;" << '\n'; + } + else { + indent(f_service_) << " return new " << resultname << "();" << '\n'; + } + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " << resultname << " getResult(I iface, " << argsname - << " args) throws org.apache.thrift.TException {" << endl; + << " args) throws org.apache.thrift.TException {" << '\n'; indent_up(); if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = getEmptyResultInstance();" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -4026,7 +4053,7 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); } @@ -4049,13 +4076,13 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << make_valid_java_identifier((*f_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) { indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -4063,34 +4090,34 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function f_service_ << indent() << "}"; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << type_name((*x_iter)->get_type(), false, false) << " " - << make_valid_java_identifier((*x_iter)->get_name()) << ") {" << endl; + << make_valid_java_identifier((*x_iter)->get_name()) << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << make_valid_java_identifier((*x_iter)->get_name()) << " = " - << make_valid_java_identifier((*x_iter)->get_name()) << ";" << endl; + << make_valid_java_identifier((*x_iter)->get_name()) << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { f_service_ << "}"; } } - f_service_ << endl; + f_service_ << '\n'; } if (tfunction->is_oneway()) { - indent(f_service_) << "return null;" << endl; + indent(f_service_) << "return null;" << '\n'; } else { - indent(f_service_) << "return result;" << endl; + indent(f_service_) << "return result;" << '\n'; } indent_down(); indent(f_service_) << "}"; // Close function - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -4154,12 +4181,12 @@ void t_java_generator::generate_deserialize_field(ostream& out, default: throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } - out << endl; + out << '\n'; } else if (type->is_enum()) { indent(out) << name << " = " << type_name(tfield->get_type(), true, false, false, true) + ".findByValue(iprot.readI32());" - << endl; + << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), type_name(type).c_str()); @@ -4172,15 +4199,15 @@ void t_java_generator::generate_deserialize_field(ostream& out, void t_java_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { if (reuse_objects_) { - indent(out) << "if (" << prefix << " == null) {" << endl; + indent(out) << "if (" << prefix << " == null) {" << '\n'; indent_up(); } - indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl; + indent(out) << prefix << " = new " << type_name(tstruct) << "();" << '\n'; if (reuse_objects_) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << prefix << ".read(iprot);" << endl; + indent(out) << prefix << ".read(iprot);" << '\n'; } /** @@ -4207,31 +4234,31 @@ void t_java_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin();" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin();" - << endl; + << '\n'; } else if (ttype->is_list()) { indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin();" - << endl; + << '\n'; } } else { // Declare variables, read header if (ttype->is_map()) { indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " - << type_to_enum(((t_map*)ttype)->get_val_type()) << "); " << endl; + << type_to_enum(((t_map*)ttype)->get_val_type()) << "); " << '\n'; } else if (ttype->is_set()) { indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin(" - << type_to_enum(((t_set*)ttype)->get_elem_type()) << ");" << endl; + << type_to_enum(((t_set*)ttype)->get_elem_type()) << ");" << '\n'; } else if (ttype->is_list()) { indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin(" - << type_to_enum(((t_list*)ttype)->get_elem_type()) << ");" << endl; + << type_to_enum(((t_list*)ttype)->get_elem_type()) << ");" << '\n'; } } if (reuse_objects_) { - indent(out) << "if (" << prefix << " == null) {" << endl; + indent(out) << "if (" << prefix << " == null) {" << '\n'; indent_up(); } @@ -4243,18 +4270,18 @@ void t_java_generator::generate_deserialize_container(ostream& out, // construct the collection correctly i.e. with appropriate size/type if (is_enum_set(ttype) || is_enum_map(ttype)) { - out << "(" << inner_enum_type_name(ttype) << ");" << endl; + out << "(" << inner_enum_type_name(ttype) << ");" << '\n'; } else if (sorted_containers_ && (ttype->is_map() || ttype->is_set())) { // TreeSet and TreeMap don't have any constructor which takes a capacity as an argument - out << "();" << endl; + out << "();" << '\n'; } else { out << "(" << (ttype->is_list() ? "" : "2*") << obj << ".size" - << ");" << endl; + << ");" << '\n'; } if (reuse_objects_) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (ttype->is_map()) { @@ -4270,11 +4297,11 @@ void t_java_generator::generate_deserialize_container(ostream& out, if (has_metadata) { // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } } scope_down(out); @@ -4293,14 +4320,14 @@ void t_java_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, reuse_objects_, false) << endl; - indent(out) << declare_field(&fval, reuse_objects_, false) << endl; + indent(out) << declare_field(&fkey, reuse_objects_, false) << '\n'; + indent(out) << declare_field(&fval, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); @@ -4308,22 +4335,22 @@ void t_java_generator::generate_deserialize_map_element(ostream& out, generate_deserialize_field(out, &fval, "", has_metadata); if (get_true_type(fkey.get_type())->is_enum()) { - indent(out) << "if (" << key << " != null)" << endl; + indent(out) << "if (" << key << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".put(" << key << ", " << val << ");" << endl; + indent(out) << prefix << ".put(" << key << ", " << val << ");" << '\n'; if (get_true_type(fkey.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(fkey.get_type())->is_base_type()) { - indent(out) << key << " = null;" << endl; + indent(out) << key << " = null;" << '\n'; } if (reuse_objects_ && !get_true_type(fval.get_type())->is_base_type()) { - indent(out) << val << " = null;" << endl; + indent(out) << val << " = null;" << '\n'; } } @@ -4338,30 +4365,30 @@ void t_java_generator::generate_deserialize_set_element(ostream& out, string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem, reuse_objects_, false) << endl; + indent(out) << declare_field(&felem, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); generate_deserialize_field(out, &felem, "", has_metadata); if (get_true_type(felem.get_type())->is_enum()) { - indent(out) << "if (" << elem << " != null)" << endl; + indent(out) << "if (" << elem << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; if (get_true_type(felem.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(felem.get_type())->is_base_type()) { - indent(out) << elem << " = null;" << endl; + indent(out) << elem << " = null;" << '\n'; } } @@ -4376,30 +4403,30 @@ void t_java_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem, reuse_objects_, false) << endl; + indent(out) << declare_field(&felem, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); generate_deserialize_field(out, &felem, "", has_metadata); if (get_true_type(felem.get_type())->is_enum()) { - indent(out) << "if (" << elem << " != null)" << endl; + indent(out) << "if (" << elem << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; if (get_true_type(felem.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(felem.get_type())->is_base_type()) { - indent(out) << elem << " = null;" << endl; + indent(out) << elem << " = null;" << '\n'; } } @@ -4425,7 +4452,7 @@ void t_java_generator::generate_serialize_field(ostream& out, } else if (type->is_container()) { generate_serialize_container(out, type, prefix + make_valid_java_identifier(tfield->get_name()) + postfix, has_metadata); } else if (type->is_enum()) { - indent(out) << "oprot.writeI32(" << prefix + make_valid_java_identifier(tfield->get_name()) + postfix << ".getValue());" << endl; + indent(out) << "oprot.writeI32(" << prefix + make_valid_java_identifier(tfield->get_name()) + postfix << ".getValue());" << '\n'; } else if (type->is_base_type()) { string name = prefix + make_valid_java_identifier(tfield->get_name()) + postfix; indent(out) << "oprot."; @@ -4470,7 +4497,7 @@ void t_java_generator::generate_serialize_field(ostream& out, } else if (type->is_enum()) { out << "writeI32(struct." << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s%s' TYPE '%s'\n", prefix.c_str(), tfield->get_name().c_str(), postfix.c_str(), type_name(type).c_str()); @@ -4485,7 +4512,7 @@ void t_java_generator::generate_serialize_field(ostream& out, */ void t_java_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -4505,18 +4532,18 @@ void t_java_generator::generate_serialize_container(ostream& out, indent(out) << "oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix << ".size()));" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new org.apache.thrift.protocol.TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } } else { - indent(out) << "oprot.writeI32(" << prefix << ".size());" << endl; + indent(out) << "oprot.writeI32(" << prefix << ".size());" << '\n'; } string iter = tmp("_iter"); @@ -4533,7 +4560,7 @@ void t_java_generator::generate_serialize_container(ostream& out, << prefix << ")"; } - out << endl; + out << '\n'; scope_up(out); if (ttype->is_map()) { generate_serialize_map_element(out, (t_map*)ttype, iter, prefix, has_metadata); @@ -4546,11 +4573,11 @@ void t_java_generator::generate_serialize_container(ostream& out, if (has_metadata) { if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } } @@ -5080,7 +5107,7 @@ void t_java_generator::generate_deep_copy_container(ostream& out, // deep copy of base types can be done much more efficiently than iterating over all the // elements manually indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "(" << source_name << ");" << endl; + << type_name(container, false, true) << "(" << source_name << ");" << '\n'; return; } @@ -5095,10 +5122,10 @@ void t_java_generator::generate_deep_copy_container(ostream& out, if (is_enum_set(container)) { indent(out) << type_name(type, true, false) << " " << result_name << " = " << type_name(container, false, true, true) << ".noneOf(" << constructor_args << ");" - << endl; + << '\n'; } else { indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "(" << constructor_args << ");" << endl; + << type_name(container, false, true) << "(" << constructor_args << ");" << '\n'; } std::string iterator_element_name = source_name_p1 + "_element"; @@ -5110,17 +5137,17 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << "for (java.util.Map.Entry<" << type_name(key_type, true, false) << ", " << type_name(val_type, true, false) << "> " << iterator_element_name << " : " - << source_name << ".entrySet()) {" << endl; + << source_name << ".entrySet()) {" << '\n'; indent_up(); - out << endl; + out << '\n'; indent(out) << type_name(key_type, true, false) << " " << iterator_element_name - << "_key = " << iterator_element_name << ".getKey();" << endl; + << "_key = " << iterator_element_name << ".getKey();" << '\n'; indent(out) << type_name(val_type, true, false) << " " << iterator_element_name - << "_value = " << iterator_element_name << ".getValue();" << endl; + << "_value = " << iterator_element_name << ".getValue();" << '\n'; - out << endl; + out << '\n'; if (key_type->is_container()) { generate_deep_copy_container(out, iterator_element_name + "_key", "", @@ -5129,10 +5156,10 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << type_name(key_type, true, false) << " " << result_element_name << "_key = "; generate_deep_copy_non_container(out, iterator_element_name + "_key", result_element_name + "_key", key_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; if (val_type->is_container()) { generate_deep_copy_container(out, iterator_element_name + "_value", "", @@ -5141,16 +5168,16 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << type_name(val_type, true, false) << " " << result_element_name << "_value = "; generate_deep_copy_non_container(out, iterator_element_name + "_value", result_element_name + "_value", val_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; indent(out) << result_name << ".put(" << result_element_name << "_key, " << result_element_name - << "_value);" << endl; + << "_value);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { t_type* elem_type; @@ -5162,32 +5189,32 @@ void t_java_generator::generate_deep_copy_container(ostream& out, } indent(out) << "for (" << type_name(elem_type, true, false) << " " << iterator_element_name - << " : " << source_name << ") {" << endl; + << " : " << source_name << ") {" << '\n'; indent_up(); if (elem_type->is_container()) { // recursive deep copy generate_deep_copy_container(out, iterator_element_name, "", result_element_name, elem_type); - indent(out) << result_name << ".add(" << result_element_name << ");" << endl; + indent(out) << result_name << ".add(" << result_element_name << ");" << '\n'; } else { // iterative copy if (elem_type->is_binary()) { indent(out) << "java.nio.ByteBuffer temp_binary_element = "; generate_deep_copy_non_container(out, iterator_element_name, "temp_binary_element", elem_type); - out << ";" << endl; - indent(out) << result_name << ".add(temp_binary_element);" << endl; + out << ";" << '\n'; + indent(out) << result_name << ".add(temp_binary_element);" << '\n'; } else { indent(out) << result_name << ".add("; generate_deep_copy_non_container(out, iterator_element_name, result_name, elem_type); - out << ");" << endl; + out << ");" << '\n'; } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -5224,14 +5251,14 @@ std::string t_java_generator::generate_isset_check(std::string field_name) { void t_java_generator::generate_isset_set(ostream& out, t_field* field, string prefix) { if (!type_can_be_null(field->get_type())) { indent(out) << prefix << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } void t_java_generator::generate_struct_desc(ostream& out, t_struct* tstruct) { indent(out) << "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new " "org.apache.thrift.protocol.TStruct(\"" - << tstruct->get_name() << "\");" << endl; + << tstruct->get_name() << "\");" << '\n'; } void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) { @@ -5243,24 +5270,24 @@ void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) { << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new org.apache.thrift.protocol.TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " - << "(short)" << (*m_iter)->get_key() << ");" << endl; + << "(short)" << (*m_iter)->get_key() << ");" << '\n'; } } void t_java_generator::generate_scheme_map(ostream& out, t_struct* tstruct) { indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory " "STANDARD_SCHEME_FACTORY = new " - << tstruct->get_name() << "StandardSchemeFactory();" << endl; + << tstruct->get_name() << "StandardSchemeFactory();" << '\n'; indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new " - << tstruct->get_name() << "TupleSchemeFactory();" << endl; + << tstruct->get_name() << "TupleSchemeFactory();" << '\n'; } void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tstruct) { indent(out) << "/** The set of fields this struct contains, along with convenience methods for " "finding and manipulating them. */" - << endl; - indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << endl; + << '\n'; + indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << '\n'; indent_up(); bool first = true; @@ -5268,7 +5295,7 @@ void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tst vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; generate_java_doc(out, *m_iter); @@ -5276,87 +5303,87 @@ void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tst << ", \"" << (*m_iter)->get_name() << "\")"; } - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; indent(out) << "private static final java.util.Map byName = new " "java.util.HashMap();" - << endl; - out << endl; + << '\n'; + out << '\n'; - indent(out) << "static {" << endl; - indent(out) << " for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {" << endl; - indent(out) << " byName.put(field.getFieldName(), field);" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "static {" << '\n'; + indent(out) << " for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {" << '\n'; + indent(out) << " byName.put(field.getFieldName(), field);" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * Find the _Fields constant that matches fieldId, or null if its not found." - << endl; - indent(out) << " */" << endl; - indent(out) << java_nullable_annotation() << endl; - indent(out) << "public static _Fields findByThriftId(int fieldId) {" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << "public static _Fields findByThriftId(int fieldId) {" << '\n'; indent_up(); - indent(out) << "switch(fieldId) {" << endl; + indent(out) << "switch(fieldId) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "case " << (*m_iter)->get_key() << ": // " - << constant_name((*m_iter)->get_name()) << endl; - indent(out) << " return " << constant_name((*m_iter)->get_name()) << ";" << endl; + << constant_name((*m_iter)->get_name()) << '\n'; + indent(out) << " return " << constant_name((*m_iter)->get_name()) << ";" << '\n'; } - indent(out) << "default:" << endl; - indent(out) << " return null;" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; - - indent(out) << "/**" << endl; - indent(out) << " * Find the _Fields constant that matches fieldId, throwing an exception" << endl; - indent(out) << " * if it is not found." << endl; - indent(out) << " */" << endl; - indent(out) << "public static _Fields findByThriftIdOrThrow(int fieldId) {" << endl; - indent(out) << " _Fields fields = findByThriftId(fieldId);" << endl; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << "/**" << '\n'; + indent(out) << " * Find the _Fields constant that matches fieldId, throwing an exception" << '\n'; + indent(out) << " * if it is not found." << '\n'; + indent(out) << " */" << '\n'; + indent(out) << "public static _Fields findByThriftIdOrThrow(int fieldId) {" << '\n'; + indent(out) << " _Fields fields = findByThriftId(fieldId);" << '\n'; indent(out) << " if (fields == null) throw new java.lang.IllegalArgumentException(\"Field \" + " "fieldId + " "\" doesn't exist!\");" - << endl; - indent(out) << " return fields;" << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << " return fields;" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * Find the _Fields constant that matches name, or null if its not found." - << endl; - indent(out) << " */" << endl; - indent(out) << java_nullable_annotation() << endl; - indent(out) << "public static _Fields findByName(java.lang.String name) {" << endl; - indent(out) << " return byName.get(name);" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << "private final short _thriftId;" << endl; - indent(out) << "private final java.lang.String _fieldName;" << endl << endl; - - indent(out) << "_Fields(short thriftId, java.lang.String fieldName) {" << endl; - indent(out) << " _thriftId = thriftId;" << endl; - indent(out) << " _fieldName = fieldName;" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << java_override_annotation() << endl; - indent(out) << "public short getThriftFieldId() {" << endl; - indent(out) << " return _thriftId;" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << java_override_annotation() << endl; - indent(out) << "public java.lang.String getFieldName() {" << endl; - indent(out) << " return _fieldName;" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << "public static _Fields findByName(java.lang.String name) {" << '\n'; + indent(out) << " return byName.get(name);" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << "private final short _thriftId;" << '\n'; + indent(out) << "private final java.lang.String _fieldName;" << '\n' << '\n'; + + indent(out) << "_Fields(short thriftId, java.lang.String fieldName) {" << '\n'; + indent(out) << " _thriftId = thriftId;" << '\n'; + indent(out) << " _fieldName = fieldName;" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public short getThriftFieldId() {" << '\n'; + indent(out) << " return _thriftId;" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public java.lang.String getFieldName() {" << '\n'; + indent(out) << " return _fieldName;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } t_java_generator::isset_type t_java_generator::needs_isset(t_struct* tstruct, @@ -5390,8 +5417,8 @@ t_java_generator::isset_type t_java_generator::needs_isset(t_struct* tstruct, } void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; - indent(out) << "public void clear() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public void clear() {" << '\n'; indent_up(); for (auto field : tstruct->get_members()) { @@ -5404,13 +5431,13 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t if (type_can_be_null(t)) { if (reuse_objects_ && (t->is_container() || t->is_struct())) { - indent(out) << "if (this." << make_valid_java_identifier(field->get_name()) << " != null) {" << endl; + indent(out) << "if (this." << make_valid_java_identifier(field->get_name()) << " != null) {" << '\n'; indent_up(); - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << ".clear();" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << ".clear();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = null;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = null;" << '\n'; } continue; } @@ -5418,7 +5445,7 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t // must be a base type // means it also needs to be explicitly unset indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(false);" - << endl; + << '\n'; t_base_type* base_type = (t_base_type*)t; switch (base_type->get_base()) { @@ -5426,13 +5453,13 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0;" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0.0;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0.0;" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = false;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = false;" << '\n'; break; default: throw "unsupported type: " + base_type->get_name() + " for field " + field->get_name(); @@ -5440,7 +5467,7 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // generates java method to serialize (in the Java sense) the object @@ -5448,24 +5475,24 @@ void t_java_generator::generate_java_struct_write_object(ostream& out, t_struct* (void)tstruct; indent(out) << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {" - << endl; - indent(out) << " try {" << endl; + << '\n'; + indent(out) << " try {" << '\n'; indent(out) << " write(new org.apache.thrift.protocol.TCompactProtocol(new " "org.apache.thrift.transport.TIOStreamTransport(out)));" - << endl; - indent(out) << " } catch (org.apache.thrift.TException te) {" << endl; + << '\n'; + indent(out) << " } catch (org.apache.thrift.TException te) {" << '\n'; indent(out) << " throw new java.io.IOException(te" << (android_legacy_ ? ".getMessage()" : "") - << ");" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + << ");" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; } // generates java method to serialize (in the Java sense) the object void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* tstruct) { indent(out) << "private void readObject(java.io.ObjectInputStream in) throws " "java.io.IOException, java.lang.ClassNotFoundException {" - << endl; - indent(out) << " try {" << endl; + << '\n'; + indent(out) << " try {" << '\n'; if (!tstruct->is_union()) { switch (needs_isset(tstruct)) { case ISSET_NONE: @@ -5473,174 +5500,174 @@ void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* case ISSET_PRIMITIVE: indent(out) << " // it doesn't seem like you should have to do this, but java " "serialization is wacky, and doesn't call the default constructor." - << endl; - indent(out) << " __isset_bitfield = 0;" << endl; + << '\n'; + indent(out) << " __isset_bitfield = 0;" << '\n'; break; case ISSET_BITSET: indent(out) << " // it doesn't seem like you should have to do this, but java " "serialization is wacky, and doesn't call the default constructor." - << endl; - indent(out) << " __isset_bit_vector = new java.util.BitSet(1);" << endl; + << '\n'; + indent(out) << " __isset_bit_vector = new java.util.BitSet(1);" << '\n'; break; } } indent(out) << " read(new org.apache.thrift.protocol.TCompactProtocol(new " "org.apache.thrift.transport.TIOStreamTransport(in)));" - << endl; - indent(out) << " } catch (org.apache.thrift.TException te) {" << endl; + << '\n'; + indent(out) << " } catch (org.apache.thrift.TException te) {" << '\n'; indent(out) << " throw new java.io.IOException(te" << (android_legacy_ ? ".getMessage()" : "") - << ");" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + << ");" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_standard_reader(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - out << indent() << "org.apache.thrift.protocol.TField schemeField;" << endl - << indent() << "iprot.readStructBegin();" << endl; + out << indent() << "org.apache.thrift.protocol.TField schemeField;" << '\n' + << indent() << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "schemeField = iprot.readFieldBegin();" << endl; + indent(out) << "schemeField = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { " << endl; + indent(out) << "if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (schemeField.id) {" << endl; + indent(out) << "switch (schemeField.id) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "case " << (*f_iter)->get_key() << ": // " - << constant_name((*f_iter)->get_name()) << endl; + << constant_name((*f_iter)->get_name()) << '\n'; indent_up(); indent(out) << "if (schemeField.type == " << type_to_enum((*f_iter)->get_type()) << ") {" - << endl; + << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "struct.", true); indent(out) << "struct." << "set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; indent_down(); - out << indent() << "} else { " << endl + out << indent() << "} else { " << '\n' << indent() << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" - << endl - << indent() << "}" << endl - << indent() << "break;" << endl; + << '\n' + << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << indent() << "iprot.readStructEnd();" << endl; + out << indent() << "iprot.readStructEnd();" << '\n'; // in non-beans style, check for required fields of primitive type // (which can be checked here but not in the general validate method) if (!bean_style_) { - out << endl + out << '\n' << indent() << "// check for required fields of primitive type, which can't be " "checked in the validate method" - << endl; + << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { - out << indent() << "if (!struct." << generate_isset_check(*f_iter) << ") {" << endl + out << indent() << "if (!struct." << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" << (*f_iter)->get_name() - << "' was not found in serialized data! Struct: \" + toString());" << endl - << indent() << "}" << endl; + << "' was not found in serialized data! Struct: \" + toString());" << '\n' + << indent() << "}" << '\n'; } } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "struct.validate();" << endl; + indent(out) << "struct.validate();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_java_generator::generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result) { indent_up(); - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "struct.validate();" << endl << endl; + indent(out) << "struct.validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (struct." << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << endl; + out << indent() << "if (struct." << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << '\n'; indent_up(); } bool optional = ((*f_iter)->get_req() == t_field::T_OPTIONAL) || (is_result && !null_allowed); if (optional) { indent(out) << "if (" - << "struct." << generate_isset_check((*f_iter)) << ") {" << endl; + << "struct." << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "struct.", "", true); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (optional) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // Write the struct map - out << indent() << "oprot.writeFieldStop();" << endl - << indent() << "oprot.writeStructEnd();" << endl; + out << indent() << "oprot.writeFieldStop();" << '\n' + << indent() << "oprot.writeStructEnd();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; indent_down(); } @@ -5649,38 +5676,38 @@ void t_java_generator::generate_java_struct_standard_scheme(ostream& out, bool is_result) { indent(out) << "private static class " << tstruct->get_name() << "StandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" - << endl; + << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << tstruct->get_name() << "StandardScheme getScheme() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << tstruct->get_name() << "StandardScheme getScheme() {" << '\n'; indent_up(); - indent(out) << "return new " << tstruct->get_name() << "StandardScheme();" << endl; + indent(out) << "return new " << tstruct->get_name() << "StandardScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; out << indent() << "private static class " << tstruct->get_name() << "StandardScheme extends org.apache.thrift.scheme.StandardScheme<" << make_valid_java_identifier(tstruct->get_name()) - << "> {" << endl - << endl; + << "> {" << '\n' + << '\n'; indent_up(); generate_standard_reader(out, tstruct); indent_down(); - out << endl; + out << '\n'; generate_standard_writer(out, tstruct, is_result); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol prot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.protocol.TTupleProtocol iprot = " "(org.apache.thrift.protocol.TTupleProtocol) prot;" - << endl; + << '\n'; int optional_count = 0; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -5692,39 +5719,39 @@ void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* if ((*f_iter)->get_req() == t_field::T_REQUIRED) { generate_deserialize_field(out, (*f_iter), "struct.", false); indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } if (optional_count > 0) { indent(out) << "java.util.BitSet incoming = iprot.readBitSet(" << optional_count << ");" - << endl; + << '\n'; int i = 0; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (incoming.get(" << i << ")) {" << endl; + indent(out) << "if (incoming.get(" << i << ")) {" << '\n'; indent_up(); generate_deserialize_field(out, (*f_iter), "struct.", false); indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; i++; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol prot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.protocol.TTupleProtocol oprot = " "(org.apache.thrift.protocol.TTupleProtocol) prot;" - << endl; + << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -5741,70 +5768,70 @@ void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* } } if (has_optional) { - indent(out) << "java.util.BitSet optionals = new java.util.BitSet();" << endl; + indent(out) << "java.util.BitSet optionals = new java.util.BitSet();" << '\n'; int i = 0; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (struct." << generate_isset_check((*f_iter)) << ") {" << endl; + indent(out) << "if (struct." << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); - indent(out) << "optionals.set(" << i << ");" << endl; + indent(out) << "optionals.set(" << i << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; i++; } } - indent(out) << "oprot.writeBitSet(optionals, " << optional_count << ");" << endl; + indent(out) << "oprot.writeBitSet(optionals, " << optional_count << ");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (struct." << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (struct." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); generate_serialize_field(out, (*f_iter), "struct.", "", false); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct) { indent(out) << "private static class " << tstruct->get_name() - << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << endl; + << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << tstruct->get_name() << "TupleScheme getScheme() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << tstruct->get_name() << "TupleScheme getScheme() {" << '\n'; indent_up(); - indent(out) << "return new " << tstruct->get_name() << "TupleScheme();" << endl; + indent(out) << "return new " << tstruct->get_name() << "TupleScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; out << indent() << "private static class " << tstruct->get_name() << "TupleScheme extends org.apache.thrift.scheme.TupleScheme<" << make_valid_java_identifier(tstruct->get_name()) << "> {" - << endl - << endl; + << '\n' + << '\n'; indent_up(); generate_java_struct_tuple_writer(out, tstruct); - out << endl; + out << '\n'; generate_java_struct_tuple_reader(out, tstruct); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_java_scheme_lookup(ostream& out) { indent(out) << "private static S scheme(" - << "org.apache.thrift.protocol.TProtocol proto) {" << endl; + << "org.apache.thrift.protocol.TProtocol proto) {" << '\n'; indent_up(); indent(out) << "return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) " << "? STANDARD_SCHEME_FACTORY " << ": TUPLE_SCHEME_FACTORY" - << ").getScheme();" << endl; + << ").getScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_javax_generated_annotation(ostream& out) { @@ -5817,11 +5844,11 @@ void t_java_generator::generate_javax_generated_annotation(ostream& out) { } if (undated_generated_annotations_) { - out << ")" << endl; + out << ")" << '\n'; } else { indent(out) << ", date = \"" << (now->tm_year + 1900) << "-" << setfill('0') << setw(2) << (now->tm_mon + 1) << "-" << setfill('0') << setw(2) << now->tm_mday << "\")" - << endl; + << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc index d8d9056306c..e2c3a395cdc 100644 --- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Java code generator. * @@ -339,7 +337,7 @@ void t_javame_generator::generate_enum(t_enum* tenum) { generate_java_doc(f_enum, tenum); indent(f_enum) << "public class " << tenum->get_name() << " implements org.apache.thrift.TEnum "; scope_up(f_enum); - f_enum << endl; + f_enum << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -347,53 +345,53 @@ void t_javame_generator::generate_enum(t_enum* tenum) { int value = (*c_iter)->get_value(); generate_java_doc(f_enum, *c_iter); indent(f_enum) << "public static final " << tenum->get_name() << " " << (*c_iter)->get_name() - << " = new " << tenum->get_name() << "(" << value << ");" << endl; + << " = new " << tenum->get_name() << "(" << value << ");" << '\n'; } - f_enum << endl; + f_enum << '\n'; // Field for thriftCode - indent(f_enum) << "private final int value;" << endl << endl; + indent(f_enum) << "private final int value;" << '\n' << '\n'; - indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << endl; - indent(f_enum) << " this.value = value;" << endl; - indent(f_enum) << "}" << endl << endl; + indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << '\n'; + indent(f_enum) << " this.value = value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Get the integer value of this enum value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << "public int getValue() {" << endl; - indent(f_enum) << " return value;" << endl; - indent(f_enum) << "}" << endl << endl; + << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << "public int getValue() {" << '\n'; + indent(f_enum) << " return value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Find a the enum type by its integer value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " * @return null if the value is not found." << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << endl; + << '\n'; + indent(f_enum) << " * @return null if the value is not found." << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << '\n'; indent_up(); - indent(f_enum) << "switch (value) {" << endl; + indent(f_enum) << "switch (value) {" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << "case " << value << ":" << endl; - indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << endl; + indent(f_enum) << "case " << value << ":" << '\n'; + indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << '\n'; } - indent(f_enum) << "default:" << endl; - indent(f_enum) << " return null;" << endl; + indent(f_enum) << "default:" << '\n'; + indent(f_enum) << " return null;" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; scope_down(f_enum); @@ -415,7 +413,7 @@ void t_javame_generator::generate_consts(std::vector consts) { // Print header f_consts << autogen_comment() << java_package() << java_type_imports(); - f_consts << "public class " << program_name_ << "Constants {" << endl << endl; + f_consts << "public class " << program_name_ << "Constants {" << '\n' << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -426,7 +424,7 @@ void t_javame_generator::generate_consts(std::vector consts) { false); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -449,17 +447,17 @@ void t_javame_generator::print_const_value(std::ostream& out, } if (type->is_base_type()) { string v2 = render_const_value(out, name, type, value); - out << name << " = " << v2 << ";" << endl << endl; + out << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { - out << name << " = " << render_const_value(out, name, type, value) << ";" << endl << endl; + out << name << " = " << render_const_value(out, name, type, value) << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { @@ -475,17 +473,17 @@ void t_javame_generator::print_const_value(std::ostream& out, string val = render_const_value(out, name, field_type, v_iter->second); indent(out) << name << "."; std::string cap_name = get_cap_name(v_iter->first->get_string()); - out << "set" << cap_name << "(" << val << ");" << endl; + out << "set" << cap_name << "(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_map()) { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* ktype = ((t_map*)type)->get_key_type(); @@ -496,17 +494,17 @@ void t_javame_generator::print_const_value(std::ostream& out, string key = render_const_value(out, name, ktype, v_iter->first); string val = render_const_value(out, name, vtype, v_iter->second); indent(out) << name << ".put(" << box_type(ktype, key) << ", " << box_type(vtype, val) << ");" - << endl; + << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* etype; @@ -520,17 +518,17 @@ void t_javame_generator::print_const_value(std::ostream& out, for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, name, etype, *v_iter); if (type->is_list()) { - indent(out) << name << ".addElement(" << box_type(etype, val) << ");" << endl; + indent(out) << name << ".addElement(" << box_type(etype, val) << ");" << '\n'; } else { indent(out) << name << ".put(" << box_type(etype, val) << ", " << box_type(etype, val) - << ");" << endl; + << ");" << '\n'; } } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else { throw "compiler error: no const of type " + type->get_name(); } @@ -673,27 +671,27 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) { generate_struct_desc(f_struct, tstruct); generate_field_descs(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_constructor(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_abstract_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_getters_and_setters(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_comparisons(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_hashcode(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; scope_down(f_struct); @@ -701,33 +699,33 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) { } void t_javame_generator::generate_union_constructor(ostream& out, t_struct* tstruct) { - indent(out) << "public " << type_name(tstruct) << "() {" << endl; - indent(out) << " super();" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << type_name(tstruct) << "() {" << '\n'; + indent(out) << " super();" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "public " << type_name(tstruct) << "(_Fields setField, Object value) {" << endl; - indent(out) << " super(setField, value);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << type_name(tstruct) << "(_Fields setField, Object value) {" << '\n'; + indent(out) << " super(setField, value);" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(" << type_name(tstruct) << " other) {" - << endl; - indent(out) << " super(other);" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " super(other);" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; // generate "constructors" for each field const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" - << type_name((*m_iter)->get_type()) << " value) {" << endl; - indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl; - indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << endl; - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + << type_name((*m_iter)->get_type()) << " value) {" << '\n'; + indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << '\n'; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; } } @@ -740,59 +738,59 @@ void t_javame_generator::generate_union_getters_and_setters(ostream& out, t_stru if (first) { first = false; } else { - out << endl; + out << '\n'; } t_field* field = (*m_iter); generate_java_doc(out, field); indent(out) << "public " << type_name(field->get_type()) << " get" - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" - << endl; - indent(out) << " } else {" << endl; + << '\n'; + indent(out) << " } else {" << '\n'; indent(out) << " throw new RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; generate_java_doc(out, field); indent(out) << "public void set" << get_cap_name(field->get_name()) << "(" - << type_name(field->get_type()) << " value) {" << endl; + << type_name(field->get_type()) << " value) {" << '\n'; if (type_can_be_null(field->get_type())) { - indent(out) << " if (value == null) throw new NullPointerException();" << endl; + indent(out) << " if (value == null) throw new NullPointerException();" << '\n'; } - indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << endl; - indent(out) << " value_ = value;" << endl; - indent(out) << "}" << endl; + indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << '\n'; + indent(out) << " value_ = value;" << '\n'; + indent(out) << "}" << '\n'; } } void t_javame_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) { generate_check_type(out, tstruct); - out << endl; + out << '\n'; generate_read_value(out, tstruct); - out << endl; + out << '\n'; generate_write_value(out, tstruct); - out << endl; + out << '\n'; generate_get_field_desc(out, tstruct); - out << endl; + out << '\n'; generate_get_struct_desc(out, tstruct); - out << endl; + out << '\n'; } void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) { indent(out) << "protected void checkType(_Fields setField, Object value) throws ClassCastException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -801,37 +799,37 @@ void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent(out) << " if (value instanceof " << type_name(field->get_type(), true, false, true) - << ") {" << endl; - indent(out) << " break;" << endl; - indent(out) << " }" << endl; + << ") {" << '\n'; + indent(out) << " break;" << '\n'; + indent(out) << " }" << '\n'; indent(out) << " throw new ClassCastException(\"Was expecting value of type " << type_name(field->get_type(), true, false) << " for field '" << field->get_name() - << "', but got \" + value.getClass().getSimpleName());" << endl; + << "', but got \" + value.getClass().getSimpleName());" << '\n'; // do the real check here } - indent(out) << "default:" << endl; - indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) { indent(out) << "protected Object readValue(TProtocol iprot, TField field) throws TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -840,48 +838,48 @@ void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << constant_name(field->get_name()) << "_FIELD_DESC.type) {" - << endl; + << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); - indent(out) << "} else {" << endl; - indent(out) << " TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << " return null;" << endl; - indent(out) << "}" << endl; + indent(out) << "} else {" << '\n'; + indent(out) << " TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << " return null;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new IllegalStateException(\"setField wasn't null, but didn't match any " - "of the case statements!\");" << endl; + "of the case statements!\");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "return null;" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) { - indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << endl; + indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -890,100 +888,100 @@ void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field, ""); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new IllegalStateException(\"Cannot write union with unknown field \" + " - "setField_);" << endl; + "setField_);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) { - indent(out) << "protected TField getFieldDesc(_Fields setField) {" << endl; + indent(out) << "protected TField getFieldDesc(_Fields setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; - indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; + indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << '\n'; } - indent(out) << "default:" << endl; - indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << "protected TStruct getStructDesc() {" << endl; - indent(out) << " return STRUCT_DESC;" << endl; - indent(out) << "}" << endl; + indent(out) << "protected TStruct getStructDesc() {" << '\n'; + indent(out) << " return STRUCT_DESC;" << '\n'; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) { // equality - indent(out) << "public boolean equals(Object other) {" << endl; - indent(out) << " if (other instanceof " << tstruct->get_name() << ") {" << endl; - indent(out) << " return equals((" << tstruct->get_name() << ")other);" << endl; - indent(out) << " } else {" << endl; - indent(out) << " return false;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << "public boolean equals(Object other) {" << '\n'; + indent(out) << " if (other instanceof " << tstruct->get_name() << ") {" << '\n'; + indent(out) << " return equals((" << tstruct->get_name() << ")other);" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " return false;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; - indent(out) << "public boolean equals(" << tstruct->get_name() << " other) {" << endl; + indent(out) << "public boolean equals(" << tstruct->get_name() << " other) {" << '\n'; indent(out) << " return other != null && getSetField() == other.getSetField() && " - "getFieldValue().equals(other.getFieldValue());" << endl; - indent(out) << "}" << endl; - out << endl; + "getFieldValue().equals(other.getFieldValue());" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent(out) << " int lastComparison = TBaseHelper.compareTo(getSetField(), other.getSetField());" - << endl; - indent(out) << " if (lastComparison == 0) {" << endl; + << '\n'; + indent(out) << " if (lastComparison == 0) {" << '\n'; indent(out) << " return TBaseHelper.compareTo(getFieldValue(), other.getFieldValue());" - << endl; - indent(out) << " }" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; } void t_javame_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * If you'd like this to perform more respectably, use the hashcode generator option." - << endl; - indent(out) << " */" << endl; - indent(out) << "public int hashCode() {" << endl; - indent(out) << " return 0;" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << "public int hashCode() {" << '\n'; + indent(out) << " return 0;" << '\n'; + indent(out) << "}" << '\n'; } /** @@ -1021,43 +1019,43 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << endl; + out << '\n'; generate_field_descs(out, tstruct); - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "private "; - out << declare_field(*m_iter, false) << endl; + out << declare_field(*m_iter, false) << '\n'; } // isset data if (members.size() > 0) { - out << endl; + out << '\n'; - indent(out) << "// isset id assignments" << endl; + indent(out) << "// isset id assignments" << '\n'; int i = 0; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";" - << endl; + << '\n'; i++; } } if (i > 0) { - indent(out) << "private boolean[] __isset_vector = new boolean[" << i << "];" << endl; + indent(out) << "private boolean[] __isset_vector = new boolean[" << i << "];" << '\n'; } - out << endl; + out << '\n'; } bool all_optional_members = true; // Default constructor - indent(out) << "public " << tstruct->get_name() << "() {" << endl; + indent(out) << "public " << tstruct->get_name() << "() {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); @@ -1074,49 +1072,49 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (!members.empty() && !all_optional_members) { // Full constructor for all fields - indent(out) << "public " << tstruct->get_name() << "(" << endl; + indent(out) << "public " << tstruct->get_name() << "(" << '\n'; indent_up(); bool first = true; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << type_name((*m_iter)->get_type()) << " " << (*m_iter)->get_name(); } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - indent(out) << "this();" << endl; + indent(out) << "this();" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { indent(out) << "this." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << ";" - << endl; + << '\n'; generate_isset_set(out, (*m_iter)); } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // copy constructor - indent(out) << "/**" << endl; - indent(out) << " * Performs a deep copy on other." << endl; - indent(out) << " */" << endl; + indent(out) << "/**" << '\n'; + indent(out) << " * Performs a deep copy on other." << '\n'; + indent(out) << " */" << '\n'; indent(out) << "public " << tstruct->get_name() << "(" << tstruct->get_name() << " other) {" - << endl; + << '\n'; indent_up(); if (has_bit_vector(tstruct)) { indent(out) << "System.arraycopy(other.__isset_vector, 0, __isset_vector, 0, " - "other.__isset_vector.length);" << endl; + "other.__isset_vector.length);" << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1126,32 +1124,32 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, bool can_be_null = type_can_be_null(type); if (can_be_null) { - indent(out) << "if (other." << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (other." << generate_isset_check(field) << ") {" << '\n'; indent_up(); } if (type->is_container()) { generate_deep_copy_container(out, "other", field_name, "__this__" + field_name, type); - indent(out) << "this." << field_name << " = __this__" << field_name << ";" << endl; + indent(out) << "this." << field_name << " = __this__" << field_name << ";" << '\n'; } else { indent(out) << "this." << field_name << " = "; generate_deep_copy_non_container(out, "other." + field_name, field_name, type); - out << ";" << endl; + out << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // clone method, so that you can deep copy an object when you don't know its class. - indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; generate_java_struct_clear(out, tstruct); @@ -1170,7 +1168,7 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, generate_java_struct_tostring(out, tstruct); generate_java_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -1179,24 +1177,24 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) { - out << indent() << "public boolean equals(Object that) {" << endl; + out << indent() << "public boolean equals(Object that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl << indent() << " return false;" << endl - << indent() << "if (that instanceof " << tstruct->get_name() << ")" << endl << indent() - << " return this.equals((" << tstruct->get_name() << ")that);" << endl << indent() - << "return false;" << endl; + out << indent() << "if (that == null)" << '\n' << indent() << " return false;" << '\n' + << indent() << "if (that instanceof " << tstruct->get_name() << ")" << '\n' << indent() + << " return this.equals((" << tstruct->get_name() << ")that);" << '\n' << indent() + << "return false;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public boolean equals(" << tstruct->get_name() << " that) {" << endl; + out << indent() << "public boolean equals(" << tstruct->get_name() << " that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl << indent() << " return false;" << endl - << indent() << "if (this == that)" << endl << indent() << " return true;" << endl; + out << indent() << "if (that == null)" << '\n' << indent() << " return false;" << '\n' + << indent() << "if (this == that)" << '\n' << indent() << " return true;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); // Most existing Thrift code does not use isset or optional/required, @@ -1214,14 +1212,14 @@ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* t that_present += " && that." + generate_isset_check(*m_iter); } - out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << endl - << indent() << "boolean that_present_" << name << " = " << that_present << ";" << endl + out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << '\n' + << indent() << "boolean that_present_" << name << " = " << that_present << ";" << '\n' << indent() << "if (" - << "this_present_" << name << " || that_present_" << name << ") {" << endl; + << "this_present_" << name << " || that_present_" << name << ") {" << '\n'; indent_up(); out << indent() << "if (!(" - << "this_present_" << name << " && that_present_" << name << "))" << endl << indent() - << " return false;" << endl; + << "this_present_" << name << " && that_present_" << name << "))" << '\n' << indent() + << " return false;" << '\n'; if (t->is_binary()) { unequal = "TBaseHelper.compareTo(this." + name + ", that." + name + ") != 0"; @@ -1231,66 +1229,66 @@ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* t unequal = "this." + name + " != that." + name; } - out << indent() << "if (" << unequal << ")" << endl << indent() << " return false;" << endl; + out << indent() << "if (" << unequal << ")" << '\n' << indent() << " return false;" << '\n'; scope_down(out); } - out << endl; - indent(out) << "return true;" << endl; + out << '\n'; + indent(out) << "return true;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public int hashCode() {" << endl; + out << indent() << "public int hashCode() {" << '\n'; indent_up(); - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) { - indent(out) << "public int compareTo(Object otherObject) {" << endl; - // indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << "public int compareTo(Object otherObject) {" << '\n'; + // indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent_up(); - indent(out) << "if (!getClass().equals(otherObject.getClass())) {" << endl; + indent(out) << "if (!getClass().equals(otherObject.getClass())) {" << '\n'; indent(out) << " return getClass().getName().compareTo(otherObject.getClass().getName());" - << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; indent(out) << type_name(tstruct) << " other = (" << type_name(tstruct) << ")otherObject;"; - indent(out) << "int lastComparison = 0;" << endl; - out << endl; + indent(out) << "int lastComparison = 0;" << '\n'; + out << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = *m_iter; indent(out) << "lastComparison = TBaseHelper.compareTo(" << generate_isset_check(field) - << ", other." << generate_isset_check(field) << ");" << endl; - indent(out) << "if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; + << ", other." << generate_isset_check(field) << ");" << '\n'; + indent(out) << "if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "if (" << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(field) << ") {" << '\n'; if (field->get_type()->is_struct() || field->get_type()->is_xception()) { indent(out) << " lastComparison = this." << field->get_name() << ".compareTo(other." - << field->get_name() << ");" << endl; + << field->get_name() << ");" << '\n'; } else { indent(out) << " lastComparison = TBaseHelper.compareTo(this." << field->get_name() - << ", other." << field->get_name() << ");" << endl; + << ", other." << field->get_name() << ");" << '\n'; } - indent(out) << " if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << " if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1299,91 +1297,91 @@ void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public void read(TProtocol iprot) throws TException {" << endl; + out << indent() << "public void read(TProtocol iprot) throws TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - out << indent() << "TField field;" << endl << indent() << "iprot.readStructBegin();" << endl; + out << indent() << "TField field;" << '\n' << indent() << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (field.type == TType.STOP) { " << endl; + indent(out) << "if (field.type == TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (field.id) {" << endl; + indent(out) << "switch (field.id) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "case " << (*f_iter)->get_key() << ": // " - << constant_name((*f_iter)->get_name()) << endl; + << constant_name((*f_iter)->get_name()) << '\n'; indent_up(); - indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); generate_isset_set(out, *f_iter); indent_down(); - out << indent() << "} else { " << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "} else { " << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n' << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; - indent(out) << " TProtocolUtil.skip(iprot, field.type);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " TProtocolUtil.skip(iprot, field.type);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << indent() << "iprot.readStructEnd();" << endl; + out << indent() << "iprot.readStructEnd();" << '\n'; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // generates java method to perform various checks // (e.g. check that all required fields are set) void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public void validate() throws TException {" << endl; + indent(out) << "public void validate() throws TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << endl << indent() + out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new TProtocolException(\"Required field '" << (*f_iter)->get_name() - << "' is unset! Struct:\" + toString());" << endl << indent() << "}" << endl << endl; + << "' is unset! Struct:\" + toString());" << '\n' << indent() << "}" << '\n' << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1392,7 +1390,7 @@ void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public void write(TProtocol oprot) throws TException {" << endl; + out << indent() << "public void write(TProtocol oprot) throws TException {" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1400,46 +1398,46 @@ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tst vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl << endl; + indent(out) << "validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl; + out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << '\n'; indent_up(); } bool optional = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (optional) { - indent(out) << "if (" << generate_isset_check((*f_iter)) << ") {" << endl; + indent(out) << "if (" << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (optional) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // Write the struct map - out << indent() << "oprot.writeFieldStop();" << endl << indent() << "oprot.writeStructEnd();" - << endl; + out << indent() << "oprot.writeFieldStop();" << '\n' << indent() << "oprot.writeStructEnd();" + << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1451,62 +1449,62 @@ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tst * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public void write(TProtocol oprot) throws TException {" << endl; + out << indent() << "public void write(TProtocol oprot) throws TException {" << '\n'; indent_up(); string name = tstruct->get_name(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this." << generate_isset_check(*f_iter) << ") {" << endl; + out << "(this." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } // Write the struct map - out << endl << indent() << "oprot.writeFieldStop();" << endl << indent() - << "oprot.writeStructEnd();" << endl; + out << '\n' << indent() << "oprot.writeFieldStop();" << '\n' << indent() + << "oprot.writeStructEnd();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_javame_generator::generate_reflection_getters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); if (type->is_base_type() && !type->is_string()) { t_base_type* base_type = (t_base_type*)type; indent(out) << "return new " << type_name(type, true, false) << "(" - << (base_type->is_bool() ? "is" : "get") << cap_name << "());" << endl << endl; + << (base_type->is_bool() ? "is" : "get") << cap_name << "());" << '\n' << '\n'; } else { - indent(out) << "return get" << cap_name << "();" << endl << endl; + indent(out) << "return get" << cap_name << "();" << '\n' << '\n'; } indent_down(); @@ -1516,14 +1514,14 @@ void t_javame_generator::generate_reflection_setters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; - indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << endl; - indent(out) << "}" << endl; - indent(out) << "break;" << endl << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; + indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "break;" << '\n' << '\n'; indent_down(); } @@ -1568,13 +1566,13 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* if (type->is_container()) { // Method to return the size of the collection indent(out) << "public int get" << cap_name; - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? 0 : " - << "this." << field_name << ".size();" << endl; + << "this." << field_name << ".size();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } if (type->is_set() || type->is_list()) { @@ -1588,35 +1586,35 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* // Iterator getter for sets and lists indent(out) << "public Enumeration get" << cap_name; - out << get_cap_name("Enumeration() {") << endl; + out << get_cap_name("Enumeration() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? null : " - << "this." << field_name << ".elements();" << endl; + << "this." << field_name << ".elements();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Add to set or list, create if the set/list is null indent(out); out << "public void add" << get_cap_name("to"); - out << cap_name << "(" << type_name(element_type) << " elem) {" << endl; + out << cap_name << "(" << type_name(element_type) << " elem) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "();" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (type->is_set()) { indent(out) << "this." << field_name << ".put(" << box_type(element_type, "elem") << ", " - << box_type(element_type, "elem") << ");" << endl; + << box_type(element_type, "elem") << ");" << '\n'; } else { indent(out) << "this." << field_name << ".addElement(" << box_type(element_type, "elem") - << ");" << endl; + << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else if (type->is_map()) { // Put to map @@ -1625,18 +1623,18 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* indent(out); out << "public void putTo" << cap_name << "(" << type_name(key_type, true) << " key, " - << type_name(val_type, true) << " val) {" << endl; + << type_name(val_type, true) << " val) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "();" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".put(key, val);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".put(key, val);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Simple getter @@ -1647,60 +1645,60 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Simple setter generate_java_doc(out, field); indent(out) << "public "; out << "void"; - out << " set" << cap_name << "(" << type_name(type) << " " << field_name << ") {" << endl; + out << " set" << cap_name << "(" << type_name(type) << " " << field_name << ") {" << '\n'; indent_up(); - indent(out) << "this." << field_name << " = " << field_name << ";" << endl; + indent(out) << "this." << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter - indent(out) << "public void unset" << cap_name << "() {" << endl; + indent(out) << "public void unset" << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "__isset_vector[" << isset_field_id(field) << "] = false;" << endl; + indent(out) << "__isset_vector[" << isset_field_id(field) << "] = false;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "/** Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise */" << endl; - indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << endl; + << " is set (has been assigned a value) and false otherwise */" << '\n'; + indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << field_name << " != null;" << endl; + indent(out) << "return this." << field_name << " != null;" << '\n'; } else { - indent(out) << "return __isset_vector[" << isset_field_id(field) << "];" << endl; + indent(out) << "return __isset_vector[" << isset_field_id(field) << "];" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public void set" << cap_name << get_cap_name("isSet") << "(boolean value) {" - << endl; + << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "if (!value) {" << endl; - indent(out) << " this." << field_name << " = null;" << endl; - indent(out) << "}" << endl; + indent(out) << "if (!value) {" << '\n'; + indent(out) << " this." << field_name << " = null;" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "__isset_vector[" << isset_field_id(field) << "] = value;" << endl; + indent(out) << "__isset_vector[" << isset_field_id(field) << "] = value;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -1710,12 +1708,12 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) { - out << indent() << "public String toString() {" << endl; + out << indent() << "public String toString() {" << '\n'; indent_up(); out << indent() << "StringBuffer sb = new StringBuffer(\"" << tstruct->get_name() << "(\");" - << endl; - out << indent() << "boolean first = true;" << endl << endl; + << '\n'; + out << indent() << "boolean first = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1723,46 +1721,46 @@ void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* t for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) sb.append(\", \");" << endl; + indent(out) << "if (!first) sb.append(\", \");" << '\n'; } - indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << endl; + indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << endl; - indent(out) << " sb.append(\"null\");" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << '\n'; + indent(out) << " sb.append(\"null\");" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (field->get_type()->is_binary()) { - indent(out) << "TBaseHelper.toString(this." << field->get_name() << ", sb);" << endl; + indent(out) << "TBaseHelper.toString(this." << field->get_name() << ", sb);" << '\n'; } else { - indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << endl; + indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "sb.append(\")\");" << endl << indent() << "return sb.toString();" << endl; + out << indent() << "sb.append(\")\");" << '\n' << indent() << "return sb.toString();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1821,7 +1819,7 @@ std::string t_javame_generator::get_java_type_string(t_type* type) { } void t_javame_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { - out << endl; + out << '\n'; indent_up(); indent_up(); if (type->is_struct() || type->is_xception()) { @@ -1871,7 +1869,7 @@ void t_javame_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports(); - f_service_ << "public class " << service_name_ << " {" << endl << endl; + f_service_ << "public class " << service_name_ << " {" << '\n' << '\n'; indent_up(); // Generate the three main parts of the service @@ -1881,7 +1879,7 @@ void t_javame_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; f_service_.close(); } @@ -1892,7 +1890,7 @@ void t_javame_generator::generate_service(t_service* tservice) { */ void t_javame_generator::generate_primitive_service_interface(t_service* tservice) { f_service_ << indent() << "public interface Iface extends " << service_name_ << "Iface { }" - << endl << endl; + << '\n' << '\n'; string f_interface_name = package_dir_ + "/" + service_name_ + "Iface.java"; ofstream_with_content_based_conditional_update f_iface; @@ -1905,15 +1903,15 @@ void t_javame_generator::generate_primitive_service_interface(t_service* tservic f_iface << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports(); generate_java_doc(f_iface, tservice); - f_iface << "public interface " << service_name_ << "Iface" << extends_iface << " {" << endl - << endl; + f_iface << "public interface " << service_name_ << "Iface" << extends_iface << " {" << '\n' + << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_iface, *f_iter); - f_iface << " public " << function_signature(*f_iter) << ";" << endl << endl; + f_iface << " public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } - f_iface << "}" << endl << endl; + f_iface << "}" << '\n' << '\n'; } /** @@ -1930,16 +1928,16 @@ void t_javame_generator::generate_service_interface(t_service* tservice) { } generate_java_doc(f_service_, tservice); - f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface Iface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_service_, *f_iter); - indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -1971,41 +1969,41 @@ void t_javame_generator::generate_service_client(t_service* tservice) { } indent(f_service_) << "public static class Client" << extends_client - << " implements TServiceClient, Iface {" << endl; + << " implements TServiceClient, Iface {" << '\n'; indent_up(); - indent(f_service_) << "public Client(TProtocol prot)" << endl; + indent(f_service_) << "public Client(TProtocol prot)" << '\n'; scope_up(f_service_); - indent(f_service_) << "this(prot, prot);" << endl; + indent(f_service_) << "this(prot, prot);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public Client(TProtocol iprot, TProtocol oprot)" << endl; + indent(f_service_) << "public Client(TProtocol iprot, TProtocol oprot)" << '\n'; scope_up(f_service_); if (extends.empty()) { - f_service_ << indent() << "iprot_ = iprot;" << endl << indent() << "oprot_ = oprot;" << endl; + f_service_ << indent() << "iprot_ = iprot;" << '\n' << indent() << "oprot_ = oprot;" << '\n'; } else { - f_service_ << indent() << "super(iprot, oprot);" << endl; + f_service_ << indent() << "super(iprot, oprot);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - f_service_ << indent() << "protected TProtocol iprot_;" << endl << indent() - << "protected TProtocol oprot_;" << endl << endl << indent() - << "protected int seqid_;" << endl << endl; + f_service_ << indent() << "protected TProtocol iprot_;" << '\n' << indent() + << "protected TProtocol oprot_;" << '\n' << '\n' << indent() + << "protected int seqid_;" << '\n' << '\n'; - indent(f_service_) << "public TProtocol getInputProtocol()" << endl; + indent(f_service_) << "public TProtocol getInputProtocol()" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.iprot_;" << endl; + indent(f_service_) << "return this.iprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public TProtocol getOutputProtocol()" << endl; + indent(f_service_) << "public TProtocol getOutputProtocol()" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.oprot_;" << endl; + indent(f_service_) << "return this.oprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate client method implementations @@ -2015,7 +2013,7 @@ void t_javame_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << "public " << function_signature(*f_iter) << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << '\n'; scope_up(f_service_); indent(f_service_) << "send_" << funname << "("; @@ -2034,17 +2032,17 @@ void t_javame_generator::generate_service_client(t_service* tservice) { } f_service_ << (*fld_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv_" << funname << "();" << endl; + f_service_ << "recv_" << funname << "();" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; t_function send_function(g_type_void, string("send_") + (*f_iter)->get_name(), @@ -2053,26 +2051,26 @@ void t_javame_generator::generate_service_client(t_service* tservice) { string argsname = (*f_iter)->get_name() + "_args"; // Open function - indent(f_service_) << "public " << function_signature(&send_function) << endl; + indent(f_service_) << "public " << function_signature(&send_function) << '\n'; scope_up(f_service_); // Serialize the request f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", ++seqid_));" << endl << indent() << argsname << " args = new " << argsname - << "();" << endl; + << ", ++seqid_));" << '\n' << indent() << argsname << " args = new " << argsname + << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << (*fld_iter)->get_name() << ");" << endl; + << (*fld_iter)->get_name() << ");" << '\n'; } - f_service_ << indent() << "args.write(oprot_);" << endl << indent() - << "oprot_.writeMessageEnd();" << endl << indent() - << "oprot_.getTransport().flush();" << endl; + f_service_ << indent() << "args.write(oprot_);" << '\n' << indent() + << "oprot_.writeMessageEnd();" << '\n' << indent() + << "oprot_.getTransport().flush();" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (!(*f_iter)->is_oneway()) { string resultname = (*f_iter)->get_name() + "_result"; @@ -2083,53 +2081,53 @@ void t_javame_generator::generate_service_client(t_service* tservice) { &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << "public " << function_signature(&recv_function) << endl; + indent(f_service_) << "public " << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << "TMessage msg = iprot_.readMessageBegin();" << endl << indent() - << "if (msg.type == TMessageType.EXCEPTION) {" << endl << indent() - << " TApplicationException x = TApplicationException.read(iprot_);" << endl - << indent() << " iprot_.readMessageEnd();" << endl << indent() << " throw x;" - << endl << indent() << "}" << endl << indent() << "if (msg.seqid != seqid_) {" - << endl << indent() + f_service_ << indent() << "TMessage msg = iprot_.readMessageBegin();" << '\n' << indent() + << "if (msg.type == TMessageType.EXCEPTION) {" << '\n' << indent() + << " TApplicationException x = TApplicationException.read(iprot_);" << '\n' + << indent() << " iprot_.readMessageEnd();" << '\n' << indent() << " throw x;" + << '\n' << indent() << "}" << '\n' << indent() << "if (msg.seqid != seqid_) {" + << '\n' << indent() << " throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, \"" - << (*f_iter)->get_name() << " failed: out of sequence response\");" << endl - << indent() << "}" << endl << indent() << resultname << " result = new " - << resultname << "();" << endl << indent() << "result.read(iprot_);" << endl - << indent() << "iprot_.readMessageEnd();" << endl; + << (*f_iter)->get_name() << " failed: out of sequence response\");" << '\n' + << indent() << "}" << '\n' << indent() << resultname << " result = new " + << resultname << "();" << '\n' << indent() << "result.read(iprot_);" << '\n' + << indent() << "iprot_.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << endl - << indent() << " return result.success;" << endl << indent() << "}" << endl; + f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << '\n' + << indent() << " return result.success;" << '\n' << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (result." << (*x_iter)->get_name() << " != null) {" << endl - << indent() << " throw result." << (*x_iter)->get_name() << ";" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << (*x_iter)->get_name() << " != null) {" << '\n' + << indent() << " throw result." << (*x_iter)->get_name() << ";" << '\n' + << indent() << "}" << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "throw new TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } /** @@ -2152,66 +2150,66 @@ void t_javame_generator::generate_service_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class Processor" << extends_processor - << " implements TProcessor {" << endl; + << " implements TProcessor {" << '\n'; indent_up(); - indent(f_service_) << "public Processor(Iface iface)" << endl; + indent(f_service_) << "public Processor(Iface iface)" << '\n'; scope_up(f_service_); if (!extends.empty()) { - f_service_ << indent() << "super(iface);" << endl; + f_service_ << indent() << "super(iface);" << '\n'; } - f_service_ << indent() << "iface_ = iface;" << endl; + f_service_ << indent() << "iface_ = iface;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "processMap_.put(\"" << (*f_iter)->get_name() << "\", new " - << (*f_iter)->get_name() << "());" << endl; + << (*f_iter)->get_name() << "());" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { f_service_ - << indent() << "protected static interface ProcessFunction {" << endl << indent() + << indent() << "protected static interface ProcessFunction {" << '\n' << indent() << " public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException;" - << endl << indent() << "}" << endl << endl; + << '\n' << indent() << "}" << '\n' << '\n'; } - f_service_ << indent() << "private Iface iface_;" << endl; + f_service_ << indent() << "private Iface iface_;" << '\n'; if (extends.empty()) { - f_service_ << indent() << "protected final Hashtable processMap_ = new Hashtable();" << endl; + f_service_ << indent() << "protected final Hashtable processMap_ = new Hashtable();" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation indent(f_service_) << "public boolean process(TProtocol iprot, TProtocol oprot) throws TException" - << endl; + << '\n'; scope_up(f_service_); - f_service_ << indent() << "TMessage msg = iprot.readMessageBegin();" << endl; + f_service_ << indent() << "TMessage msg = iprot.readMessageBegin();" << '\n'; // TODO(mcslee): validate message, was the seqid etc. legit? f_service_ - << indent() << "ProcessFunction fn = (ProcessFunction)processMap_.get(msg.name);" << endl - << indent() << "if (fn == null) {" << endl << indent() - << " TProtocolUtil.skip(iprot, TType.STRUCT);" << endl << indent() - << " iprot.readMessageEnd();" << endl << indent() + << indent() << "ProcessFunction fn = (ProcessFunction)processMap_.get(msg.name);" << '\n' + << indent() << "if (fn == null) {" << '\n' << indent() + << " TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n' << indent() + << " iprot.readMessageEnd();" << '\n' << indent() << " TApplicationException x = new " "TApplicationException(TApplicationException.UNKNOWN_METHOD, \"Invalid method name: " - "'\"+msg.name+\"'\");" << endl << indent() + "'\"+msg.name+\"'\");" << '\n' << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" - << endl << indent() << " x.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();" - << endl << indent() << " oprot.getTransport().flush();" << endl << indent() - << " return true;" << endl << indent() << "}" << endl << indent() - << "fn.process(msg.seqid, iprot, oprot);" << endl; + << '\n' << indent() << " x.write(oprot);" << '\n' << indent() << " oprot.writeMessageEnd();" + << '\n' << indent() << " oprot.getTransport().flush();" << '\n' << indent() + << " return true;" << '\n' << indent() << "}" << '\n' << indent() + << "fn.process(msg.seqid, iprot, oprot);" << '\n'; - f_service_ << indent() << "return true;" << endl; + f_service_ << indent() << "return true;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2219,7 +2217,7 @@ void t_javame_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -2257,36 +2255,36 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi (void)tservice; // Open class indent(f_service_) << "private class " << tfunction->get_name() << " implements ProcessFunction {" - << endl; + << '\n'; indent_up(); // Open function indent(f_service_) << "public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException" - << endl; + << '\n'; scope_up(f_service_); string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; - f_service_ << indent() << argsname << " args = new " << argsname << "();" << endl << indent() - << "try {" << endl; + f_service_ << indent() << argsname << " args = new " << argsname << "();" << '\n' << indent() + << "try {" << '\n'; indent_up(); - f_service_ << indent() << "args.read(iprot);" << endl; + f_service_ << indent() << "args.read(iprot);" << '\n'; indent_down(); - f_service_ << indent() << "} catch (TProtocolException e) {" << endl; + f_service_ << indent() << "} catch (TProtocolException e) {" << '\n'; indent_up(); - f_service_ << indent() << "iprot.readMessageEnd();" << endl << indent() + f_service_ << indent() << "iprot.readMessageEnd();" << '\n' << indent() << "TApplicationException x = new " "TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());" - << endl << indent() << "oprot.writeMessageBegin(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot.writeMessageEnd();" << endl - << indent() << "oprot.getTransport().flush();" << endl << indent() << "return;" - << endl; + << '\n' << indent() << "oprot.writeMessageBegin(new TMessage(\"" + << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' + << indent() << "oprot.getTransport().flush();" << '\n' << indent() << "return;" + << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "iprot.readMessageEnd();" << endl; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "iprot.readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2294,12 +2292,12 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << resultname << " result = new " << resultname << "();" << endl; + f_service_ << indent() << resultname << " result = new " << resultname << "();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); } @@ -2322,13 +2320,13 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) { f_service_ << indent() << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -2336,54 +2334,54 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi f_service_ << indent() << "}"; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << type_name((*x_iter)->get_type(), false, false) << " " - << (*x_iter)->get_name() << ") {" << endl; + << (*x_iter)->get_name() << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << (*x_iter)->get_name() << " = " - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { f_service_ << "}"; } } - f_service_ << " catch (Throwable th) {" << endl; + f_service_ << " catch (Throwable th) {" << '\n'; indent_up(); f_service_ << indent() << "TApplicationException x = new " "TApplicationException(TApplicationException.INTERNAL_ERROR, " "\"Internal error processing " << tfunction->get_name() << "\");" - << endl << indent() << "oprot.writeMessageBegin(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << endl - << indent() << "x.write(oprot);" << endl << indent() << "oprot.writeMessageEnd();" - << endl << indent() << "oprot.getTransport().flush();" << endl << indent() - << "return;" << endl; + << '\n' << indent() << "oprot.writeMessageBegin(new TMessage(\"" + << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << '\n' + << indent() << "x.write(oprot);" << '\n' << indent() << "oprot.writeMessageEnd();" + << '\n' << indent() << "oprot.getTransport().flush();" << '\n' << indent() + << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; scope_down(f_service_); // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; return; } f_service_ << indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl << indent() << "result.write(oprot);" - << endl << indent() << "oprot.writeMessageEnd();" << endl << indent() - << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n' << indent() << "result.write(oprot);" + << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' << indent() + << "oprot.getTransport().flush();" << '\n'; // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -2441,11 +2439,11 @@ void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfiel default: throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } - out << endl; + out << '\n'; } else if (type->is_enum()) { indent(out) << name << " = " << type_name(tfield->get_type(), true, false) + ".findByValue(iprot.readI32());" - << endl; + << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2459,8 +2457,8 @@ void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfiel void t_javame_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent() - << prefix << ".read(iprot);" << endl; + out << indent() << prefix << " = new " << type_name(tstruct) << "();" << '\n' << indent() + << prefix << ".read(iprot);" << '\n'; } /** @@ -2483,23 +2481,23 @@ void t_javame_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { - indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "TList " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "TList " << obj << " = iprot.readListBegin();" << '\n'; } indent(out) << prefix << " = new " << type_name(ttype, false, true) // size the collection correctly << "(" << (ttype->is_list() ? "" : "2*") << obj << ".size" - << ");" << endl; + << ");" << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); @@ -2515,11 +2513,11 @@ void t_javame_generator::generate_deserialize_container(ostream& out, // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -2536,14 +2534,14 @@ void t_javame_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); indent(out) << prefix << ".put(" << box_type(tmap->get_key_type(), key) << ", " - << box_type(tmap->get_val_type(), val) << ");" << endl; + << box_type(tmap->get_val_type(), val) << ");" << '\n'; } /** @@ -2555,12 +2553,12 @@ void t_javame_generator::generate_deserialize_set_element(ostream& out, string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); indent(out) << prefix << ".put(" << box_type(tset->get_elem_type(), elem) << ", " - << box_type(tset->get_elem_type(), elem) << ");" << endl; + << box_type(tset->get_elem_type(), elem) << ");" << '\n'; } /** @@ -2572,11 +2570,11 @@ void t_javame_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".addElement(" << box_type(tlist->get_elem_type(), elem) << ");" << endl; + indent(out) << prefix << ".addElement(" << box_type(tlist->get_elem_type(), elem) << ");" << '\n'; } /** @@ -2598,7 +2596,7 @@ void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, } else if (type->is_container()) { generate_serialize_container(out, type, prefix + tfield->get_name()); } else if (type->is_enum()) { - indent(out) << "oprot.writeI32(" << prefix + tfield->get_name() << ".getValue());" << endl; + indent(out) << "oprot.writeI32(" << prefix + tfield->get_name() << ".getValue());" << '\n'; } else if (type->is_base_type()) { string name = prefix + tfield->get_name(); indent(out) << "oprot."; @@ -2640,7 +2638,7 @@ void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2659,7 +2657,7 @@ void t_javame_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -2674,14 +2672,14 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp if (ttype->is_map()) { indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".size()));" << endl; + << ", " << prefix << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".size()));" - << endl; + << '\n'; } string iter = tmp("_iter"); @@ -2692,7 +2690,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp << ".hasMoreElements(); ) "; scope_up(out); indent(out) << key_type << " " << iter << " = (" << key_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } else if (ttype->is_set()) { string enumer = iter + "_enum"; string ele_type = type_name(((t_list*)ttype)->get_elem_type(), true); @@ -2700,7 +2698,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp << ".hasMoreElements(); ) "; scope_up(out); indent(out) << ele_type << " " << iter << " = (" << ele_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } else if (ttype->is_list()) { string enumer = iter + "_enum"; indent(out) << "for (Enumeration " << enumer << " = " << prefix << ".elements(); " << enumer @@ -2708,7 +2706,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp scope_up(out); string ele_type = type_name(((t_list*)ttype)->get_elem_type(), true); indent(out) << ele_type << " " << iter << " = (" << ele_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } if (ttype->is_map()) { @@ -2721,11 +2719,11 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } scope_down(out); @@ -3056,7 +3054,7 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, source_name = source_name_p1 + "." + source_name_p2; indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "();" << endl; + << type_name(container, false, true) << "();" << '\n'; std::string iterator_element_name = source_name_p1 + "_element"; std::string enumeration_name = source_name_p1 + "_enum"; @@ -3067,19 +3065,19 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, t_type* val_type = ((t_map*)container)->get_val_type(); indent(out) << "for (Enumeration " << enumeration_name << " = " << source_name << ".keys(); " - << enumeration_name << ".hasMoreElements(); ) {" << endl; + << enumeration_name << ".hasMoreElements(); ) {" << '\n'; indent_up(); - out << endl; + out << '\n'; indent(out) << type_name(key_type, true, false) << " " << iterator_element_name << "_key = (" << type_name(key_type, true, false) << ")" << enumeration_name << ".nextElement();" - << endl; + << '\n'; indent(out) << type_name(val_type, true, false) << " " << iterator_element_name << "_value = (" << type_name(val_type, true, false) << ")" << source_name << ".get(" - << iterator_element_name << "_key);" << endl; + << iterator_element_name << "_key);" << '\n'; - out << endl; + out << '\n'; if (key_type->is_container()) { generate_deep_copy_container(out, @@ -3093,10 +3091,10 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name + "_key", result_element_name + "_key", key_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; if (val_type->is_container()) { generate_deep_copy_container(out, @@ -3110,16 +3108,16 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name + "_value", result_element_name + "_value", val_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; indent(out) << result_name << ".put(" << result_element_name << "_key, " << result_element_name - << "_value);" << endl; + << "_value);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { t_type* elem_type; @@ -3131,19 +3129,19 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, } indent(out) << "for (Enumeration " << enumeration_name << " = " << source_name - << ".elements(); " << enumeration_name << ".hasMoreElements(); ) {" << endl; + << ".elements(); " << enumeration_name << ".hasMoreElements(); ) {" << '\n'; indent_up(); indent(out) << type_name(elem_type, true, false) << " " << iterator_element_name << " = (" << type_name(elem_type, true, false) << ")" << enumeration_name << ".nextElement();" - << endl; + << '\n'; if (elem_type->is_container()) { // recursive deep copy generate_deep_copy_container(out, iterator_element_name, "", result_element_name, elem_type); if (elem_type->is_list()) { - indent(out) << result_name << ".addElement(" << result_element_name << ");" << endl; + indent(out) << result_name << ".addElement(" << result_element_name << ");" << '\n'; } else { indent(out) << result_name << ".put(" << result_element_name << ", " << result_element_name - << ");" << endl; + << ");" << '\n'; } } else { // iterative copy @@ -3153,22 +3151,22 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name, "temp_binary_element", elem_type); - out << ";" << endl; + out << ";" << '\n'; if (elem_type->is_list()) { - indent(out) << result_name << ".addElement(temp_binary_element);" << endl; + indent(out) << result_name << ".addElement(temp_binary_element);" << '\n'; } else { - indent(out) << result_name << ".put(temp_binary_element, temp_binary_element);" << endl; + indent(out) << result_name << ".put(temp_binary_element, temp_binary_element);" << '\n'; } } else { indent(out) << result_name << ".addElement("; generate_deep_copy_non_container(out, iterator_element_name, result_name, elem_type); - out << ");" << endl; + out << ");" << '\n'; } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -3179,7 +3177,7 @@ void t_javame_generator::generate_deep_copy_non_container(ostream& out, if (type->is_base_type() || type->is_enum() || type->is_typedef()) { // binary fields need to be copied with System.arraycopy if (type->is_binary()) { - out << "new byte[" << source_name << ".length];" << endl; + out << "new byte[" << source_name << ".length];" << '\n'; indent(out) << "System.arraycopy(" << source_name << ", 0, " << dest_name << ", 0, " << source_name << ".length)"; } @@ -3206,7 +3204,7 @@ std::string t_javame_generator::generate_isset_check(std::string field_name) { void t_javame_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);" - << endl; + << '\n'; } } @@ -3221,7 +3219,7 @@ std::string t_javame_generator::get_enum_class_name(t_type* type) { void t_javame_generator::generate_struct_desc(ostream& out, t_struct* tstruct) { indent(out) << "private static final TStruct STRUCT_DESC = new TStruct(\"" << tstruct->get_name() - << "\");" << endl; + << "\");" << '\n'; } void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) { @@ -3232,7 +3230,7 @@ void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) { indent(out) << "private static final TField " << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " - << "(short)" << (*m_iter)->get_key() << ");" << endl; + << "(short)" << (*m_iter)->get_key() << ");" << '\n'; } } @@ -3249,7 +3247,7 @@ bool t_javame_generator::has_bit_vector(t_struct* tstruct) { } void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << "public void clear() {" << endl; + indent(out) << "public void clear() {" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; @@ -3266,24 +3264,24 @@ void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* true); } else { if (type_can_be_null(t)) { - indent(out) << "this." << (*m_iter)->get_name() << " = null;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = null;" << '\n'; } else { // must be a base type // means it also needs to be explicitly unset indent(out) << "set" << get_cap_name((*m_iter)->get_name()) << get_cap_name("isSet") - << "(false);" << endl; + << "(false);" << '\n'; switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_I8: case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: - indent(out) << "this." << (*m_iter)->get_name() << " = 0;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = 0;" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "this." << (*m_iter)->get_name() << " = 0.0;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = 0.0;" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "this." << (*m_iter)->get_name() << " = false;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = false;" << '\n'; break; default: // prevent gcc compiler warning break; @@ -3293,7 +3291,7 @@ void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } std::string t_javame_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc index 0e8da5963ee..402ff50da58 100644 --- a/compiler/cpp/src/thrift/generate/t_js_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc @@ -43,7 +43,6 @@ using std::stringstream; using std::unordered_map; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes static const string episode_file_name = "thrift.js.episode"; // largest consecutive integer representable by a double (2 ^ 53 - 1) static const int64_t max_safe_integer = 0x1fffffffffffff; @@ -69,6 +68,7 @@ class t_js_generator : public t_oop_generator { gen_jquery_ = false; gen_ts_ = false; gen_es6_ = false; + gen_esm_ = false; gen_episode_file_ = false; bool with_ns_ = false; @@ -84,6 +84,8 @@ class t_js_generator : public t_oop_generator { with_ns_ = true; } else if( iter->first.compare("es6") == 0) { gen_es6_ = true; + } else if ( iter->first.compare("esm") == 0) { + gen_esm_ = true; } else if( iter->first.compare("imports") == 0) { parse_imports(program, iter->second); } else if (iter->first.compare("thrift_package_output_directory") == 0) { @@ -106,6 +108,10 @@ class t_js_generator : public t_oop_generator { throw std::invalid_argument("invalid switch: [-gen js:with_ns] is only valid when using node.js"); } + if (!gen_node_ && gen_esm_) { + throw std::invalid_argument("invalid switch: [-gen js:esm] is only valid when using node.js"); + } + // Depending on the processing flags, we will update these to be ES6 compatible js_const_type_ = "var "; js_let_type_ = "var "; @@ -279,13 +285,6 @@ class t_js_generator : public t_oop_generator { return js_namespace(p); } - std::string js_export_namespace(t_program* p) { - if (gen_node_) { - return "exports."; - } - return js_namespace(p); - } - bool has_js_namespace(t_program* p) { if (no_ns_) { return false; @@ -339,17 +338,17 @@ class t_js_generator : public t_oop_generator { * @return string The documentation */ string ts_print_doc(t_doc* tdoc) { - string result = endl; + string result = "\n"; if (tdoc->has_doc()) { std::stringstream doc(tdoc->get_doc()); string item; - result += ts_indent() + "/**" + endl; + result += ts_indent() + "/**" + "\n"; while (std::getline(doc, item)) { - result += ts_indent() + " * " + item + endl; + result += ts_indent() + " * " + item + "\n"; } - result += ts_indent() + " */" + endl; + result += ts_indent() + " */" + "\n"; } return result; } @@ -375,6 +374,11 @@ class t_js_generator : public t_oop_generator { */ bool gen_es6_; + /** + * True if we should generate ES modules, instead of CommonJS. + */ + bool gen_esm_; + /** * True if we will generate an episode file. */ @@ -453,11 +457,11 @@ void t_js_generator::init_generator() { f_episode_.open(f_episode_file_path); } - const auto f_types_name = outdir + program_->get_name() + "_types.js"; + const auto f_types_name = outdir + program_->get_name() + "_types" + (gen_esm_ ? ".mjs" : ".js"); f_types_.open(f_types_name.c_str()); if (gen_episode_file_) { const auto types_module = program_->get_name() + "_types"; - f_episode_ << types_module << ":" << thrift_package_output_directory_ << "/" << types_module << endl; + f_episode_ << types_module << ":" << thrift_package_output_directory_ << "/" << types_module << '\n'; } if (gen_ts_) { @@ -469,17 +473,23 @@ void t_js_generator::init_generator() { f_types_ << autogen_comment(); if ((gen_node_ || gen_es6_) && no_ns_) { - f_types_ << "\"use strict\";" << endl << endl; + f_types_ << "\"use strict\";" << '\n' << '\n'; } - f_types_ << js_includes() << endl << render_includes() << endl; + f_types_ << js_includes() << '\n' << render_includes() << '\n'; if (gen_ts_) { - f_types_ts_ << autogen_comment() << ts_includes() << endl << render_ts_includes() << endl; + f_types_ts_ << autogen_comment() << ts_includes() << '\n' << render_ts_includes() << '\n'; } if (gen_node_) { - f_types_ << js_const_type_ << "ttypes = module.exports = {};" << endl; + if (gen_esm_) { + // Import the current module, so we can reference it as ttypes. This is + // fine in ESM, because it allows circular imports. + f_types_ << "import * as ttypes from './" + program_->get_name() + "_types.mjs';" << '\n'; + } else { + f_types_ << js_const_type_ << "ttypes = module.exports = {};" << '\n'; + } } string pns; @@ -490,11 +500,11 @@ void t_js_generator::init_generator() { if (ns_pieces.size() > 0) { for (size_t i = 0; i < ns_pieces.size(); ++i) { pns += ((i == 0) ? "" : ".") + ns_pieces[i]; - f_types_ << "if (typeof " << pns << " === 'undefined') {" << endl; - f_types_ << " " << pns << " = {};" << endl; - f_types_ << "}" << endl; - f_types_ << "" << "if (typeof module !== 'undefined' && module.exports) {" << endl; - f_types_ << " module.exports." << pns << " = " << pns << ";" << endl << "}" << endl; + f_types_ << "if (typeof " << pns << " === 'undefined') {" << '\n'; + f_types_ << " " << pns << " = {};" << '\n'; + f_types_ << "}" << '\n'; + f_types_ << "" << "if (typeof module !== 'undefined' && module.exports) {" << '\n'; + f_types_ << " module.exports." << pns << " = " << pns << ";" << '\n' << "}" << '\n'; } if (gen_ts_) { ts_module_ = pns; @@ -508,12 +518,26 @@ void t_js_generator::init_generator() { */ string t_js_generator::js_includes() { if (gen_node_) { - string result = js_const_type_ + "thrift = require('thrift');\n" - + js_const_type_ + "Thrift = thrift.Thrift;\n"; + string result; + + if (gen_esm_) { + result += "import { Thrift } from 'thrift';\n"; + } else { + result += js_const_type_ + "thrift = require('thrift');\n" + + js_const_type_ + "Thrift = thrift.Thrift;\n"; + } if (!gen_es6_) { - result += js_const_type_ + "Q = thrift.Q;\n"; + if (gen_esm_) { + result += "import { Q } from 'thrift';\n"; + } else { + result += js_const_type_ + "Q = thrift.Q;\n"; + } + } + if (gen_esm_) { + result += "import Int64 from 'node-int64';"; + } else { + result += js_const_type_ + "Int64 = require('node-int64');\n"; } - result += js_const_type_ + "Int64 = require('node-int64');\n"; return result; } string result = "if (typeof Int64 === 'undefined' && typeof require === 'function') {\n " + js_const_type_ + "Int64 = require('node-int64');\n}\n"; @@ -557,7 +581,11 @@ string t_js_generator::render_includes() { if (gen_node_) { const vector& includes = program_->get_includes(); for (auto include : includes) { - result += js_const_type_ + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('" + get_import_path(include) + "');\n"; + if (gen_esm_) { + result += "import * as " + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes from '" + get_import_path(include) + "';\n"; + } else { + result += js_const_type_ + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('" + get_import_path(include) + "');\n"; + } } if (includes.size() > 0) { result += "\n"; @@ -591,17 +619,17 @@ string t_js_generator::render_ts_includes() { string t_js_generator::get_import_path(t_program* program) { const string import_file_name(program->get_name() + "_types"); + const string import_file_name_with_extension = import_file_name + (gen_esm_ ? ".mjs" : ".js"); + if (program->get_recursive()) { - return "./" + import_file_name; + return "./" + import_file_name_with_extension; } - const string import_file_name_with_extension = import_file_name + ".js"; - - auto module_name_and_import_path_iterator = module_name_2_import_path.find(import_file_name); - if (module_name_and_import_path_iterator != module_name_2_import_path.end()) { - return module_name_and_import_path_iterator->second; - } - return "./" + import_file_name; + auto module_name_and_import_path_iterator = module_name_2_import_path.find(import_file_name); + if (module_name_and_import_path_iterator != module_name_2_import_path.end()) { + return module_name_and_import_path_iterator->second; + } + return "./" + import_file_name_with_extension; } /** @@ -639,11 +667,15 @@ void t_js_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_js_generator::generate_enum(t_enum* tenum) { - f_types_ << js_type_namespace(tenum->get_program()) << tenum->get_name() << " = {" << endl; + if (gen_esm_) { + f_types_ << "export const " << tenum->get_name() << " = {" << '\n'; + } else { + f_types_ << js_type_namespace(tenum->get_program()) << tenum->get_name() << " = {" << '\n'; + } if (gen_ts_) { f_types_ts_ << ts_print_doc(tenum) << ts_indent() << ts_declare() << "enum " - << tenum->get_name() << " {" << endl; + << tenum->get_name() << " {" << '\n'; } indent_up(); @@ -653,23 +685,23 @@ void t_js_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); if (gen_ts_) { - f_types_ts_ << ts_indent() << (*c_iter)->get_name() << " = " << value << "," << endl; + f_types_ts_ << ts_indent() << (*c_iter)->get_name() << " = " << value << "," << '\n'; // add 'value: key' in addition to 'key: value' for TypeScript enums - f_types_ << indent() << "'" << value << "' : '" << (*c_iter)->get_name() << "'," << endl; + f_types_ << indent() << "'" << value << "' : '" << (*c_iter)->get_name() << "'," << '\n'; } f_types_ << indent() << "'" << (*c_iter)->get_name() << "' : " << value; if (c_iter != constants.end() - 1) { f_types_ << ","; } - f_types_ << endl; + f_types_ << '\n'; } indent_down(); - f_types_ << "};" << endl; + f_types_ << "};" << '\n'; if (gen_ts_) { - f_types_ts_ << ts_indent() << "}" << endl; + f_types_ts_ << ts_indent() << "}" << '\n'; } } @@ -681,12 +713,16 @@ void t_js_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); t_const_value* value = tconst->get_value(); - f_types_ << js_type_namespace(program_) << name << " = "; - f_types_ << render_const_value(type, value) << ";" << endl; + if (gen_esm_) { + f_types_ << "export const " << name << " = "; + } else { + f_types_ << js_type_namespace(program_) << name << " = "; + } + f_types_ << render_const_value(type, value) << ";" << '\n'; if (gen_ts_) { f_types_ts_ << ts_print_doc(tconst) << ts_indent() << ts_declare() << js_const_type_ << name << ": " - << ts_get_type(type) << ";" << endl; + << ts_get_type(type) << ";" << '\n'; } } @@ -755,24 +791,24 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) { } if (v_iter != val.begin()) out << ","; - out << endl << indent() << render_const_value(g_type_string, v_iter->first); + out << '\n' << indent() << render_const_value(g_type_string, v_iter->first); out << " : "; out << render_const_value(field_type, v_iter->second); } indent_down(); - out << endl << indent() << "})"; + out << '\n' << indent() << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { if (v_iter != val.begin()) - out << "," << endl; + out << "," << '\n'; if (ktype->is_base_type() && ((t_base_type*)get_true_type(ktype))->get_base() == t_base_type::TYPE_I64){ out << indent() << "\"" << v_iter->first->get_integer() << "\""; @@ -784,7 +820,7 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(vtype, v_iter->second); } indent_down(); - out << endl << indent() << "}"; + out << '\n' << indent() << "}"; } else if (type->is_list() || type->is_set()) { t_type* etype; if (type->is_list()) { @@ -860,33 +896,42 @@ void t_js_generator::generate_js_struct_definition(ostream& out, vector::const_iterator m_iter; if (gen_node_) { + string commonjs_export = ""; + + if (is_exported) { + if (gen_esm_) { + out << "export "; + } else { + commonjs_export = " = module.exports." + tstruct->get_name(); + } + } + string prefix = has_js_namespace(tstruct->get_program()) ? js_namespace(tstruct->get_program()) : js_const_type_; - out << prefix << tstruct->get_name() << - (is_exported ? " = module.exports." + tstruct->get_name() : ""); + out << prefix << tstruct->get_name() << commonjs_export; if (gen_ts_) { f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class " << tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "") - << " {" << endl; + << " {" << '\n'; } } else { out << js_namespace(tstruct->get_program()) << tstruct->get_name(); if (gen_ts_) { f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class " << tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "") - << " {" << endl; + << " {" << '\n'; } } if (gen_es6_) { if (gen_node_ && is_exception) { - out << " = class extends Thrift.TException {" << endl; + out << " = class extends Thrift.TException {" << '\n'; } else { - out << " = class {" << endl; + out << " = class {" << '\n'; } indent_up(); - indent(out) << "constructor(args) {" << endl; + indent(out) << "constructor(args) {" << '\n'; } else { - out << " = function(args) {" << endl; + out << " = function(args) {" << '\n'; } indent_up(); @@ -894,13 +939,13 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Call super() method on inherited Error class if (gen_node_ && is_exception) { if (gen_es6_) { - indent(out) << "super(args);" << endl; + indent(out) << "super(args);" << '\n'; } else { indent(out) << "Thrift.TException.call(this, \"" << js_namespace(tstruct->get_program()) - << tstruct->get_name() << "\");" << endl; + << tstruct->get_name() << "\");" << '\n'; } out << indent() << "this.name = \"" << js_namespace(tstruct->get_program()) - << tstruct->get_name() << "\";" << endl; + << tstruct->get_name() << "\";" << '\n'; } // members with arguments @@ -909,9 +954,9 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && !(t->is_struct() || t->is_xception())) { dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value()); - out << indent() << "this." << (*m_iter)->get_name() << " = " << dval << ";" << endl; + out << indent() << "this." << (*m_iter)->get_name() << " = " << dval << ";" << '\n'; } else { - out << indent() << dval << ";" << endl; + out << indent() << dval << ";" << '\n'; } if (gen_ts_) { string ts_access = gen_node_ ? "public " : ""; @@ -919,11 +964,11 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Special case. Exceptions derive from Error, and error has a non optional message field. // Ignore the optional flag in this case, otherwise we will generate a incompatible field - // in the eyes of typescript. + // in the eyes of typescript. string optional_flag = is_exception && member_name == "message" ? "" : ts_get_req(*m_iter); - + f_types_ts_ << ts_indent() << ts_access << member_name << optional_flag << ": " - << ts_get_type((*m_iter)->get_type()) << ";" << endl; + << ts_get_type((*m_iter)->get_type()) << ";" << '\n'; } } @@ -934,7 +979,7 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "this." << (*m_iter)->get_name() << " = " - << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } @@ -943,28 +988,28 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if (t->is_xception()) { out << indent() << "if (args instanceof " << js_type_namespace(t->get_program()) - << t->get_name() << ") {" << endl << indent() << indent() << "this." - << (*m_iter)->get_name() << " = args;" << endl << indent() << indent() << "return;" - << endl << indent() << "}" << endl; + << t->get_name() << ") {" << '\n' << indent() << indent() << "this." + << (*m_iter)->get_name() << " = args;" << '\n' << indent() << indent() << "return;" + << '\n' << indent() << "}" << '\n'; } } - indent(out) << "if (args) {" << endl; + indent(out) << "if (args) {" << '\n'; indent_up(); if (gen_ts_) { - f_types_ts_ << endl << ts_indent() << "constructor(args?: { "; + f_types_ts_ << '\n' << ts_indent() << "constructor(args?: { "; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); - indent(out) << "if (args." << (*m_iter)->get_name() << " !== undefined && args." << (*m_iter)->get_name() << " !== null) {" << endl; + indent(out) << "if (args." << (*m_iter)->get_name() << " !== undefined && args." << (*m_iter)->get_name() << " !== null) {" << '\n'; indent_up(); indent(out) << "this." << (*m_iter)->get_name(); if (t->is_struct()) { out << (" = new " + js_type_namespace(t->get_program()) + t->get_name() + "(args."+(*m_iter)->get_name() +");"); - out << endl; + out << '\n'; } else if (t->is_container()) { t_type* etype = get_contained_type(t); string copyFunc = t->is_map() ? "Thrift.copyMap" : "Thrift.copyList"; @@ -993,53 +1038,53 @@ void t_js_generator::generate_js_struct_definition(ostream& out, out << (" = " + copyFunc + "(args." + (*m_iter)->get_name() + ", [" + type_list + "]);"); - out << endl; + out << '\n'; } else { - out << " = args." << (*m_iter)->get_name() << ";" << endl; + out << " = args." << (*m_iter)->get_name() << ";" << '\n'; } indent_down(); if (!(*m_iter)->get_req()) { - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent(out) << " throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, " - "'Required field " << (*m_iter)->get_name() << " is unset!');" << endl; + "'Required field " << (*m_iter)->get_name() << " is unset!');" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (gen_ts_) { f_types_ts_ << (*m_iter)->get_name() << ts_get_req(*m_iter) << ": " << ts_get_type((*m_iter)->get_type()) << "; "; } } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (gen_ts_) { - f_types_ts_ << "});" << endl; + f_types_ts_ << "});" << '\n'; } } // Done with constructor indent_down(); if (gen_es6_) { - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { - indent(out) << "};" << endl; + indent(out) << "};" << '\n'; } if (gen_ts_) { - f_types_ts_ << ts_indent() << "}" << endl; + f_types_ts_ << ts_indent() << "}" << '\n'; } if (!gen_es6_) { if (is_exception) { out << "Thrift.inherits(" << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ", Thrift.TException);" << endl; + << ", Thrift.TException);" << '\n'; out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype.name = '" - << tstruct->get_name() << "';" << endl; + << tstruct->get_name() << "';" << '\n'; } else { // init prototype manually if we aren't using es6 out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype = {};" - << endl; + << '\n'; } } @@ -1050,7 +1095,7 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Close out the class definition if (gen_es6_) { indent_down(); - indent(out) << "};" << endl; + indent(out) << "};" << '\n'; } } @@ -1062,84 +1107,84 @@ void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (gen_es6_) { - indent(out) << "read (input) {" << endl; + indent(out) << "[Symbol.for(\"read\")] (input) {" << '\n'; } else { indent(out) << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ".prototype.read = function(input) {" << endl; + << ".prototype[Symbol.for(\"read\")] = function(input) {" << '\n'; } indent_up(); - indent(out) << "input.readStructBegin();" << endl; + indent(out) << "input.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true) {" << endl; + indent(out) << "while (true) {" << '\n'; indent_up(); - indent(out) << js_const_type_ << "ret = input.readFieldBegin();" << endl; - indent(out) << js_const_type_ << "ftype = ret.ftype;" << endl; + indent(out) << js_const_type_ << "ret = input.readFieldBegin();" << '\n'; + indent(out) << js_const_type_ << "ftype = ret.ftype;" << '\n'; if (!fields.empty()) { - indent(out) << js_const_type_ << "fid = ret.fid;" << endl; + indent(out) << js_const_type_ << "fid = ret.fid;" << '\n'; } // Check for field STOP marker and break - indent(out) << "if (ftype == Thrift.Type.STOP) {" << endl; + indent(out) << "if (ftype == Thrift.Type.STOP) {" << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (!fields.empty()) { // Switch statement on the field we are reading - indent(out) << "switch (fid) {" << endl; + indent(out) << "switch (fid) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << (*f_iter)->get_key() << ":" << endl; - indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; - indent(out) << " input.skip(ftype);" << endl; + indent(out) << " input.skip(ftype);" << '\n'; - out << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "}" << '\n' << indent() << "break;" << '\n'; } if (fields.size() == 1) { // pseudo case to make jslint happy - indent(out) << "case 0:" << endl; - indent(out) << " input.skip(ftype);" << endl; - indent(out) << " break;" << endl; + indent(out) << "case 0:" << '\n'; + indent(out) << " input.skip(ftype);" << '\n'; + indent(out) << " break;" << '\n'; } // In the default case we skip the field - indent(out) << "default:" << endl; - indent(out) << " input.skip(ftype);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " input.skip(ftype);" << '\n'; scope_down(out); } else { - indent(out) << "input.skip(ftype);" << endl; + indent(out) << "input.skip(ftype);" << '\n'; } - indent(out) << "input.readFieldEnd();" << endl; + indent(out) << "input.readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "input.readStructEnd();" << endl; + indent(out) << "input.readStructEnd();" << '\n'; - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); if (gen_es6_) { - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { - indent(out) << "};" << endl << endl; + indent(out) << "};" << '\n' << '\n'; } } @@ -1152,44 +1197,44 @@ void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (gen_es6_) { - indent(out) << "write (output) {" << endl; + indent(out) << "[Symbol.for(\"write\")] (output) {" << '\n'; } else { indent(out) << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ".prototype.write = function(output) {" << endl; + << ".prototype[Symbol.for(\"write\")] = function(output) {" << '\n'; } indent_up(); - indent(out) << "output.writeStructBegin('" << name << "');" << endl; + indent(out) << "output.writeStructBegin('" << name << "');" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { out << indent() << "if (this." << (*f_iter)->get_name() << " !== null && this." - << (*f_iter)->get_name() << " !== undefined) {" << endl; + << (*f_iter)->get_name() << " !== undefined) {" << '\n'; indent_up(); indent(out) << "output.writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); - indent(out) << "output.writeFieldEnd();" << endl; + indent(out) << "output.writeFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << indent() << "output.writeFieldStop();" << endl << indent() << "output.writeStructEnd();" - << endl; + out << indent() << "output.writeFieldStop();" << '\n' << indent() << "output.writeStructEnd();" + << '\n'; - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); if (gen_es6_) { - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } else { - out << indent() << "};" << endl << endl; + out << indent() << "};" << '\n' << '\n'; } } @@ -1199,10 +1244,10 @@ void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) * @param tservice The service definition */ void t_js_generator::generate_service(t_service* tservice) { - string f_service_name = get_out_dir() + service_name_ + ".js"; + string f_service_name = get_out_dir() + service_name_ + (gen_esm_ ? ".mjs" : ".js"); f_service_.open(f_service_name.c_str()); if (gen_episode_file_) { - f_episode_ << service_name_ << ":" << thrift_package_output_directory_ << "/" << service_name_ << endl; + f_episode_ << service_name_ << ":" << thrift_package_output_directory_ << "/" << service_name_ << '\n'; } if (gen_ts_) { @@ -1213,58 +1258,58 @@ void t_js_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment(); if ((gen_node_ || gen_es6_) && no_ns_) { - f_service_ << "\"use strict\";" << endl << endl; + f_service_ << "\"use strict\";" << '\n' << '\n'; } - f_service_ << js_includes() << endl << render_includes() << endl; + f_service_ << js_includes() << '\n' << render_includes() << '\n'; if (gen_ts_) { if (tservice->get_extends() != nullptr) { f_service_ts_ << "/// get_extends()->get_name() - << ".d.ts\" />" << endl; + << ".d.ts\" />" << '\n'; } - f_service_ts_ << autogen_comment() << endl << ts_includes() << endl << render_ts_includes() << endl; + f_service_ts_ << autogen_comment() << '\n' << ts_includes() << '\n' << render_ts_includes() << '\n'; if (gen_node_) { - f_service_ts_ << "import ttypes = require('./" + program_->get_name() + "_types');" << endl; + f_service_ts_ << "import ttypes = require('./" + program_->get_name() + "_types');" << '\n'; // Generate type aliases // enum vector const& enums = program_->get_enums(); vector::const_iterator e_iter; for (e_iter = enums.begin(); e_iter != enums.end(); ++e_iter) { f_service_ts_ << "import " << (*e_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*e_iter)->get_name() << endl; + << js_namespace(program_) << (*e_iter)->get_name() << '\n'; } // const vector const& consts = program_->get_consts(); vector::const_iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { f_service_ts_ << "import " << (*c_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*c_iter)->get_name() << endl; + << js_namespace(program_) << (*c_iter)->get_name() << '\n'; } // exception vector const& exceptions = program_->get_xceptions(); vector::const_iterator x_iter; for (x_iter = exceptions.begin(); x_iter != exceptions.end(); ++x_iter) { f_service_ts_ << "import " << (*x_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*x_iter)->get_name() << endl; + << js_namespace(program_) << (*x_iter)->get_name() << '\n'; } // structs vector const& structs = program_->get_structs(); vector::const_iterator s_iter; for (s_iter = structs.begin(); s_iter != structs.end(); ++s_iter) { f_service_ts_ << "import " << (*s_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*s_iter)->get_name() << endl; + << js_namespace(program_) << (*s_iter)->get_name() << '\n'; } } else { - f_service_ts_ << "import { " << program_->get_name() << " } from \"./" << program_->get_name() << "_types\";" << endl << endl; + f_service_ts_ << "import { " << program_->get_name() << " } from \"./" << program_->get_name() << "_types\";" << '\n' << '\n'; } if (!ts_module_.empty()) { if (gen_node_) { f_service_ts_ << "declare module " << ts_module_ << " {"; } else { - f_service_ts_ << "declare module \"./" << program_->get_name() << "_types\" {" << endl; + f_service_ts_ << "declare module \"./" << program_->get_name() << "_types\" {" << '\n'; indent_up(); - f_service_ts_ << ts_indent() << "module " << program_->get_name() << " {" << endl; + f_service_ts_ << ts_indent() << "module " << program_->get_name() << " {" << '\n'; indent_up(); } } @@ -1273,17 +1318,21 @@ void t_js_generator::generate_service(t_service* tservice) { if (gen_node_) { if (tservice->get_extends() != nullptr) { f_service_ << js_const_type_ << tservice->get_extends()->get_name() << " = require('./" - << tservice->get_extends()->get_name() << "');" << endl << js_const_type_ + << tservice->get_extends()->get_name() << "');" << '\n' << js_const_type_ << tservice->get_extends()->get_name() - << "Client = " << tservice->get_extends()->get_name() << ".Client;" << endl + << "Client = " << tservice->get_extends()->get_name() << ".Client;" << '\n' << js_const_type_ << tservice->get_extends()->get_name() - << "Processor = " << tservice->get_extends()->get_name() << ".Processor;" << endl; + << "Processor = " << tservice->get_extends()->get_name() << ".Processor;" << '\n'; f_service_ts_ << "import " << tservice->get_extends()->get_name() << " = require('./" - << tservice->get_extends()->get_name() << "');" << endl; + << tservice->get_extends()->get_name() << "');" << '\n'; } - f_service_ << js_const_type_ << "ttypes = require('./" + program_->get_name() + "_types');" << endl; + if (gen_esm_) { + f_service_ << "import * as ttypes from './" + program_->get_name() + "_types.mjs';" << '\n'; + } else { + f_service_ << js_const_type_ << "ttypes = require('./" + program_->get_name() + "_types');" << '\n'; + } } generate_service_helpers(tservice); @@ -1298,11 +1347,11 @@ void t_js_generator::generate_service(t_service* tservice) { if (gen_ts_) { if (!ts_module_.empty()) { if (gen_node_) { - f_service_ts_ << "}" << endl; + f_service_ts_ << "}" << '\n'; } else { indent_down(); - f_service_ts_ << ts_indent() << "}" << endl; - f_service_ts_ << "}" << endl; + f_service_ts_ << ts_indent() << "}" << '\n'; + f_service_ts_ << "}" << '\n'; } } f_service_ts_.close(); @@ -1318,27 +1367,28 @@ void t_js_generator::generate_service_processor(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - if (gen_node_) { - string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_; - f_service_ << prefix << service_name_ << "Processor = " << "exports.Processor"; - if (gen_ts_) { - f_service_ts_ << endl << "declare class Processor "; - if (tservice->get_extends() != nullptr) { - f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Processor "; - } - f_service_ts_ << "{" << endl; - indent_up(); + std::string service_var; + if (!gen_node_ || has_js_namespace(tservice->get_program())) { + service_var = js_namespace(tservice->get_program()) + service_name_ + "Processor"; + f_service_ << service_var; + } else { + service_var = service_name_ + "Processor"; + f_service_ << js_const_type_ << service_var; + }; + if (gen_node_ && gen_ts_) { + f_service_ts_ << '\n' << "declare class Processor "; + if (tservice->get_extends() != nullptr) { + f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Processor "; + } + f_service_ts_ << "{" << '\n'; + indent_up(); - if(tservice->get_extends() == nullptr) { - f_service_ts_ << ts_indent() << "private _handler: object;" << endl << endl; - } - f_service_ts_ << ts_indent() << "constructor(handler: object);" << endl; - f_service_ts_ << ts_indent() << "process(input: thrift.TProtocol, output: thrift.TProtocol): void;" << endl; - indent_down(); + if(tservice->get_extends() == nullptr) { + f_service_ts_ << ts_indent() << "private _handler: object;" << '\n' << '\n'; } - } else { - f_service_ << js_namespace(tservice->get_program()) << service_name_ << "Processor = " - << "exports.Processor"; + f_service_ts_ << ts_indent() << "constructor(handler: object);" << '\n'; + f_service_ts_ << ts_indent() << "process(input: thrift.TProtocol, output: thrift.TProtocol): void;" << '\n'; + indent_down(); } bool is_subclass_service = tservice->get_extends() != nullptr; @@ -1346,65 +1396,65 @@ void t_js_generator::generate_service_processor(t_service* tservice) { // ES6 Constructor if (gen_es6_) { if (is_subclass_service) { - f_service_ << " = class " << service_name_ << "Processor extends " << tservice->get_extends()->get_name() << "Processor {" << endl; + f_service_ << " = class " << service_name_ << "Processor extends " << tservice->get_extends()->get_name() << "Processor {" << '\n'; } else { - f_service_ << " = class " << service_name_ << "Processor {" << endl; + f_service_ << " = class " << service_name_ << "Processor {" << '\n'; } indent_up(); - indent(f_service_) << "constructor(handler) {" << endl; + indent(f_service_) << "constructor(handler) {" << '\n'; } else { - f_service_ << " = function(handler) {" << endl; + f_service_ << " = function(handler) {" << '\n'; } indent_up(); if (gen_es6_ && is_subclass_service) { - indent(f_service_) << "super(handler);" << endl; + indent(f_service_) << "super(handler);" << '\n'; } - indent(f_service_) << "this._handler = handler;" << endl; + indent(f_service_) << "this._handler = handler;" << '\n'; indent_down(); // Done with constructor if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // ES5 service inheritance if (!gen_es6_ && is_subclass_service) { indent(f_service_) << "Thrift.inherits(" << js_namespace(tservice->get_program()) << service_name_ << "Processor, " << tservice->get_extends()->get_name() - << "Processor);" << endl; + << "Processor);" << '\n'; } // Generate the server implementation if (gen_es6_) { - indent(f_service_) << "process (input, output) {" << endl; + indent(f_service_) << "process (input, output) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Processor.prototype.process = function(input, output) {" << endl; + << "Processor.prototype.process = function(input, output) {" << '\n'; } indent_up(); - indent(f_service_) << js_const_type_ << "r = input.readMessageBegin();" << endl << indent() - << "if (this['process_' + r.fname]) {" << endl << indent() - << " return this['process_' + r.fname].call(this, r.rseqid, input, output);" << endl - << indent() << "} else {" << endl << indent() << " input.skip(Thrift.Type.STRUCT);" - << endl << indent() << " input.readMessageEnd();" << endl << indent() + indent(f_service_) << js_const_type_ << "r = input.readMessageBegin();" << '\n' << indent() + << "if (this['process_' + r.fname]) {" << '\n' << indent() + << " return this['process_' + r.fname].call(this, r.rseqid, input, output);" << '\n' + << indent() << "} else {" << '\n' << indent() << " input.skip(Thrift.Type.STRUCT);" + << '\n' << indent() << " input.readMessageEnd();" << '\n' << indent() << " " << js_const_type_ << "x = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN_METHOD, " - "'Unknown function ' + r.fname);" << endl << indent() + "'Unknown function ' + r.fname);" << '\n' << indent() << " output.writeMessageBegin(r.fname, Thrift.MessageType.EXCEPTION, r.rseqid);" - << endl << indent() << " x.write(output);" << endl << indent() - << " output.writeMessageEnd();" << endl << indent() << " output.flush();" << endl - << indent() << "}" << endl; + << '\n' << indent() << " x[Symbol.for(\"write\")](output);" << '\n' << indent() + << " output.writeMessageEnd();" << '\n' << indent() << " output.flush();" << '\n' + << indent() << "}" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // Generate the process subfunctions @@ -1415,10 +1465,16 @@ void t_js_generator::generate_service_processor(t_service* tservice) { // Close off the processor class definition if (gen_es6_) { indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } if (gen_node_ && gen_ts_) { - f_service_ts_ << "}" << endl; + f_service_ts_ << "}" << '\n'; + } + + if(gen_esm_) { + f_service_ << "export { " << service_var << " as Processor };" << '\n'; + } else { + f_service_ << "exports.Processor = " << service_var << ";" << '\n'; } } @@ -1429,15 +1485,15 @@ void t_js_generator::generate_service_processor(t_service* tservice) { */ void t_js_generator::generate_process_function(t_service* tservice, t_function* tfunction) { if (gen_es6_) { - indent(f_service_) << "process_" + tfunction->get_name() + " (seqid, input, output) {" << endl; + indent(f_service_) << "process_" + tfunction->get_name() + " (seqid, input, output) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Processor.prototype.process_" + tfunction->get_name() - + " = function(seqid, input, output) {" << endl; + + " = function(seqid, input, output) {" << '\n'; } if (gen_ts_) { indent_up(); - f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << endl; + f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << '\n'; indent_down(); } @@ -1447,8 +1503,8 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* string resultname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name() + "_result"; - indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << endl << indent() - << "args.read(input);" << endl << indent() << "input.readMessageEnd();" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << '\n' << indent() + << "args[Symbol.for(\"read\")](input);" << '\n' << indent() << "input.readMessageEnd();" << '\n'; // Generate the function call t_struct* arg_struct = tfunction->get_arglist(); @@ -1469,58 +1525,58 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } return; } // Promise style invocation indent(f_service_) << "if (this._handler." << tfunction->get_name() - << ".length === " << fields.size() << ") {" << endl; + << ".length === " << fields.size() << ") {" << '\n'; indent_up(); if (gen_es6_) { - indent(f_service_) << "new Promise((resolve) => resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << endl; + indent(f_service_) << "new Promise((resolve) => resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << '\n'; } else { string maybeComma = (fields.size() > 0 ? "," : ""); indent(f_service_) << "Q.fcall(this._handler." << tfunction->get_name() << ".bind(this._handler)" - << maybeComma << endl; + << maybeComma << '\n'; } indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string maybeComma = (f_iter != fields.end() - 1 ? "," : ""); - indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << endl; + indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << '\n'; } indent_down(); if (gen_es6_) { - indent(f_service_) << "))).then(result => {" << endl; + indent(f_service_) << "))).then(result => {" << '\n'; } else { - indent(f_service_) << ").then(function(result) {" << endl; + indent(f_service_) << ").then(function(result) {" << '\n'; } indent_up(); - f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << endl + f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl << indent() - << "result_obj.write(output);" << endl << indent() << "output.writeMessageEnd();" << endl - << indent() << "output.flush();" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n' << indent() + << "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent() << "output.writeMessageEnd();" << '\n' + << indent() << "output.flush();" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}).catch(err => {" << endl; + indent(f_service_) << "}).catch(err => {" << '\n'; } else { - indent(f_service_) << "}).catch(function (err) {" << endl; + indent(f_service_) << "}).catch(function (err) {" << '\n'; } indent_up(); - indent(f_service_) << js_let_type_ << "result;" << endl; + indent(f_service_) << js_let_type_ << "result;" << '\n'; bool has_exception = false; t_struct* exceptions = tfunction->get_xceptions(); @@ -1542,36 +1598,36 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } if (has_exception) { - f_service_ << ") {" << endl; + f_service_ << ") {" << '\n'; indent_up(); - f_service_ << indent() << "result = new " << resultname << "(err);" << endl << indent() + f_service_ << indent() << "result = new " << resultname << "(err);" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); } f_service_ << indent() << "result = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN," - " err.message);" << endl << indent() << "output.writeMessageBegin(\"" - << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << endl; + " err.message);" << '\n' << indent() << "output.writeMessageBegin(\"" + << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n'; if (has_exception) { indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } - f_service_ << indent() << "result.write(output);" << endl << indent() - << "output.writeMessageEnd();" << endl << indent() << "output.flush();" << endl; + f_service_ << indent() << "result[Symbol.for(\"write\")](output);" << '\n' << indent() + << "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; indent_down(); // End promise style invocation // Callback style invocation - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); indent(f_service_) << "this._handler." << tfunction->get_name() << "("; @@ -1580,12 +1636,12 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } if (gen_es6_) { - f_service_ << "(err, result) => {" << endl; + f_service_ << "(err, result) => {" << '\n'; } else { - f_service_ << "function (err, result) {" << endl; + f_service_ << "function (err, result) {" << '\n'; } indent_up(); - indent(f_service_) << js_let_type_ << "result_obj;" << endl; + indent(f_service_) << js_let_type_ << "result_obj;" << '\n'; indent(f_service_) << "if ((err === null || typeof err === 'undefined')"; if (has_exception) { @@ -1597,35 +1653,35 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } } } - f_service_ << ") {" << endl; + f_service_ << ") {" << '\n'; indent_up(); f_service_ << indent() << "result_obj = new " << resultname - << "((err !== null || typeof err === 'undefined') ? err : {success: result});" << endl << indent() + << "((err !== null || typeof err === 'undefined') ? err : {success: result});" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); f_service_ << indent() << "result_obj = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN," - " err.message);" << endl << indent() << "output.writeMessageBegin(\"" - << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << endl; + " err.message);" << '\n' << indent() << "output.writeMessageBegin(\"" + << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl << indent() << "result_obj.write(output);" << endl << indent() - << "output.writeMessageEnd();" << endl << indent() << "output.flush();" << endl; + f_service_ << indent() << "}" << '\n' << indent() << "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent() + << "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; // End callback style invocation indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } } @@ -1642,7 +1698,7 @@ void t_js_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "//HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_ << "//HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1703,27 +1759,27 @@ void t_js_generator::generate_service_client(t_service* tservice) { bool is_subclass_service = tservice->get_extends() != nullptr; + string client_var = js_namespace(tservice->get_program()) + service_name_ + "Client"; if (gen_node_) { - string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_; - f_service_ << prefix << service_name_ << "Client = " << "exports.Client"; + string prefix = has_js_namespace(tservice->get_program()) ? "" : js_const_type_; + f_service_ << prefix << client_var; if (gen_ts_) { f_service_ts_ << ts_print_doc(tservice) << ts_indent() << ts_declare() << "class " << "Client "; if (tservice->get_extends() != nullptr) { f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Client "; } - f_service_ts_ << "{" << endl; + f_service_ts_ << "{" << '\n'; } } else { - f_service_ << js_namespace(tservice->get_program()) << service_name_ - << "Client"; + f_service_ << client_var; if (gen_ts_) { f_service_ts_ << ts_print_doc(tservice) << ts_indent() << ts_declare() << "class " << service_name_ << "Client "; if (is_subclass_service) { f_service_ts_ << "extends " << tservice->get_extends()->get_name() << "Client "; } - f_service_ts_ << "{" << endl; + f_service_ts_ << "{" << '\n'; } } @@ -1732,21 +1788,21 @@ void t_js_generator::generate_service_client(t_service* tservice) { if (is_subclass_service) { f_service_ << " = class " << service_name_ << "Client extends " << js_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "Client {" << endl; + << tservice->get_extends()->get_name() << "Client {" << '\n'; } else { - f_service_ << " = class " << service_name_ << "Client {" << endl; + f_service_ << " = class " << service_name_ << "Client {" << '\n'; } indent_up(); if (gen_node_) { - indent(f_service_) << "constructor(output, pClass) {" << endl; + indent(f_service_) << "constructor(output, pClass) {" << '\n'; } else { - indent(f_service_) << "constructor(input, output) {" << endl; + indent(f_service_) << "constructor(input, output) {" << '\n'; } } else { if (gen_node_) { - f_service_ << " = function(output, pClass) {" << endl; + f_service_ << " = function(output, pClass) {" << '\n'; } else { - f_service_ << " = function(input, output) {" << endl; + f_service_ << " = function(input, output) {" << '\n'; } } @@ -1754,65 +1810,65 @@ void t_js_generator::generate_service_client(t_service* tservice) { if (gen_node_) { if (gen_es6_ && is_subclass_service) { - indent(f_service_) << "super(output, pClass);" << endl; + indent(f_service_) << "super(output, pClass);" << '\n'; } - indent(f_service_) << "this.output = output;" << endl; - indent(f_service_) << "this.pClass = pClass;" << endl; - indent(f_service_) << "this._seqid = 0;" << endl; - indent(f_service_) << "this._reqs = {};" << endl; + indent(f_service_) << "this.output = output;" << '\n'; + indent(f_service_) << "this.pClass = pClass;" << '\n'; + indent(f_service_) << "this._seqid = 0;" << '\n'; + indent(f_service_) << "this._reqs = {};" << '\n'; if (gen_ts_) { if(!is_subclass_service) { - f_service_ts_ << ts_indent() << "private output: thrift.TTransport;" << endl - << ts_indent() << "private pClass: thrift.TProtocol;" << endl - << ts_indent() << "private _seqid: number;" << endl - << endl; + f_service_ts_ << ts_indent() << "private output: thrift.TTransport;" << '\n' + << ts_indent() << "private pClass: thrift.TProtocol;" << '\n' + << ts_indent() << "private _seqid: number;" << '\n' + << '\n'; } f_service_ts_ << ts_indent() << "constructor(output: thrift.TTransport, pClass: { new(trans: thrift.TTransport): thrift.TProtocol });" - << endl; + << '\n'; } } else { - indent(f_service_) << "this.input = input;" << endl; - indent(f_service_) << "this.output = (!output) ? input : output;" << endl; - indent(f_service_) << "this.seqid = 0;" << endl; + indent(f_service_) << "this.input = input;" << '\n'; + indent(f_service_) << "this.output = (!output) ? input : output;" << '\n'; + indent(f_service_) << "this.seqid = 0;" << '\n'; if (gen_ts_) { - f_service_ts_ << ts_indent() << "input: Thrift.TJSONProtocol;" << endl << ts_indent() - << "output: Thrift.TJSONProtocol;" << endl << ts_indent() << "seqid: number;" - << endl << endl << ts_indent() + f_service_ts_ << ts_indent() << "input: Thrift.TJSONProtocol;" << '\n' << ts_indent() + << "output: Thrift.TJSONProtocol;" << '\n' << ts_indent() << "seqid: number;" + << '\n' << '\n' << ts_indent() << "constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol);" - << endl; + << '\n'; } } indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; if (is_subclass_service) { indent(f_service_) << "Thrift.inherits(" << js_namespace(tservice->get_program()) << service_name_ << "Client, " << js_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "Client);" << endl; + << tservice->get_extends()->get_name() << "Client);" << '\n'; } else { // init prototype indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype = {};" << endl; + << "Client.prototype = {};" << '\n'; } } // utils for multiplexed services if (gen_node_) { if (gen_es6_) { - indent(f_service_) << "seqid () { return this._seqid; }" << endl; - indent(f_service_) << "new_seqid () { return this._seqid += 1; }" << endl; + indent(f_service_) << "seqid () { return this._seqid; }" << '\n'; + indent(f_service_) << "new_seqid () { return this._seqid += 1; }" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype.seqid = function() { return this._seqid; };" << endl + << "Client.prototype.seqid = function() { return this._seqid; };" << '\n' << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.new_seqid = function() { return this._seqid += 1; };" - << endl; + << '\n'; } } @@ -1827,144 +1883,144 @@ void t_js_generator::generate_service_client(t_service* tservice) { string arglist = argument_list(arg_struct); // Open function - f_service_ << endl; + f_service_ << '\n'; if (gen_es6_) { - indent(f_service_) << funname << " (" << arglist << ") {" << endl; + indent(f_service_) << funname << " (" << arglist << ") {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype." - << function_signature(*f_iter, "", !gen_es6_) << " {" << endl; + << function_signature(*f_iter, "", !gen_es6_) << " {" << '\n'; } indent_up(); if (gen_ts_) { // function definition without callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false) << '\n'; if (!gen_es6_) { // overload with callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << '\n'; } else { // overload with callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << '\n'; } } if (gen_es6_ && gen_node_) { - indent(f_service_) << "this._seqid = this.new_seqid();" << endl; - indent(f_service_) << js_const_type_ << "self = this;" << endl << indent() - << "return new Promise((resolve, reject) => {" << endl; + indent(f_service_) << "this._seqid = this.new_seqid();" << '\n'; + indent(f_service_) << js_const_type_ << "self = this;" << '\n' << indent() + << "return new Promise((resolve, reject) => {" << '\n'; indent_up(); - indent(f_service_) << "self._reqs[self.seqid()] = (error, result) => {" << endl; + indent(f_service_) << "self._reqs[self.seqid()] = (error, result) => {" << '\n'; indent_up(); - indent(f_service_) << "return error ? reject(error) : resolve(result);" << endl; + indent(f_service_) << "return error ? reject(error) : resolve(result);" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; - indent(f_service_) << "self.send_" << funname << "(" << arglist << ");" << endl; + indent(f_service_) << "};" << '\n'; + indent(f_service_) << "self.send_" << funname << "(" << arglist << ");" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; } else if (gen_node_) { // Node.js output ./gen-nodejs - f_service_ << indent() << "this._seqid = this.new_seqid();" << endl << indent() - << "if (callback === undefined) {" << endl; + f_service_ << indent() << "this._seqid = this.new_seqid();" << '\n' << indent() + << "if (callback === undefined) {" << '\n'; indent_up(); - f_service_ << indent() << js_const_type_ << "_defer = Q.defer();" << endl << indent() - << "this._reqs[this.seqid()] = function(error, result) {" << endl; + f_service_ << indent() << js_const_type_ << "_defer = Q.defer();" << '\n' << indent() + << "this._reqs[this.seqid()] = function(error, result) {" << '\n'; indent_up(); - indent(f_service_) << "if (error) {" << endl; + indent(f_service_) << "if (error) {" << '\n'; indent_up(); - indent(f_service_) << "_defer.reject(error);" << endl; + indent(f_service_) << "_defer.reject(error);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - indent(f_service_) << "_defer.resolve(result);" << endl; + indent(f_service_) << "_defer.resolve(result);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; - f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << endl - << indent() << "return _defer.promise;" << endl; + indent(f_service_) << "};" << '\n'; + f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << '\n' + << indent() << "return _defer.promise;" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "this._reqs[this.seqid()] = callback;" << endl << indent() - << "this.send_" << funname << "(" << arglist << ");" << endl; + f_service_ << indent() << "this._reqs[this.seqid()] = callback;" << '\n' << indent() + << "this.send_" << funname << "(" << arglist << ");" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else if (gen_es6_) { - f_service_ << indent() << js_const_type_ << "self = this;" << endl << indent() - << "return new Promise((resolve, reject) => {" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n' << indent() + << "return new Promise((resolve, reject) => {" << '\n'; indent_up(); f_service_ << indent() << "self.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "(error, result) => {" << endl; + << (arglist.empty() ? "" : ", ") << "(error, result) => {" << '\n'; indent_up(); - indent(f_service_) << "return error ? reject(error) : resolve(result);" << endl; + indent(f_service_) << "return error ? reject(error) : resolve(result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } else if (gen_jquery_) { // jQuery output ./gen-js - f_service_ << indent() << "if (callback === undefined) {" << endl; + f_service_ << indent() << "if (callback === undefined) {" << '\n'; indent_up(); - f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << endl; + f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "this.recv_" << funname << "();" << endl; + f_service_ << "this.recv_" << funname << "();" << '\n'; } indent_down(); - f_service_ << indent() << "} else {" << endl; + f_service_ << indent() << "} else {" << '\n'; indent_up(); f_service_ << indent() << js_const_type_ << "postData = this.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "true);" << endl; - f_service_ << indent() << "return this.output.getTransport()" << endl; + << (arglist.empty() ? "" : ", ") << "true);" << '\n'; + f_service_ << indent() << "return this.output.getTransport()" << '\n'; indent_up(); f_service_ << indent() << ".jqRequest(this, postData, arguments, this.recv_" << funname - << ");" << endl; + << ");" << '\n'; indent_down(); indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } else { // Standard JavaScript ./gen-js f_service_ << indent() << "this.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "callback); " << endl; + << (arglist.empty() ? "" : ", ") << "callback); " << '\n'; if (!(*f_iter)->is_oneway()) { - f_service_ << indent() << "if (!callback) {" << endl; + f_service_ << indent() << "if (!callback) {" << '\n'; f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << " return "; } - f_service_ << "this.recv_" << funname << "();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << "this.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "}" << '\n'; } } indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } else { - indent(f_service_) << "};" << endl << endl; + indent(f_service_) << "};" << '\n' << '\n'; } // Send function if (gen_es6_) { if (gen_node_) { - indent(f_service_) << "send_" << funname << " (" << arglist << ") {" << endl; + indent(f_service_) << "send_" << funname << " (" << arglist << ") {" << '\n'; } else { // ES6 js still uses callbacks here. Should refactor this to promise style later.. - indent(f_service_) << "send_" << funname << " (" << argument_list(arg_struct, true) << ") {" << endl; + indent(f_service_) << "send_" << funname << " (" << argument_list(arg_struct, true) << ") {" << '\n'; } } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.send_" - << function_signature(*f_iter, "", !gen_node_) << " {" << endl; + << function_signature(*f_iter, "", !gen_node_) << " {" << '\n'; } indent_up(); std::string outputVar; if (gen_node_) { - f_service_ << indent() << js_const_type_ << "output = new this.pClass(this.output);" << endl; + f_service_ << indent() << js_const_type_ << "output = new this.pClass(this.output);" << '\n'; outputVar = "output"; } else { outputVar = "this.output"; @@ -1980,127 +2036,127 @@ void t_js_generator::generate_service_client(t_service* tservice) { // It is possible that a method argument is named "params", we need to ensure the locally // generated identifier "params" is uniquely named std::string params_identifier = this->next_identifier_name(fields, "params"); - f_service_ << indent() << js_const_type_ << params_identifier << " = {" << endl; + f_service_ << indent() << js_const_type_ << params_identifier << " = {" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << (*fld_iter)->get_name() << ": " << (*fld_iter)->get_name(); if (fld_iter != fields.end()-1) { - f_service_ << "," << endl; + f_service_ << "," << '\n'; } else { - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; // NOTE: "args" is a reserved keyword, so no need to generate a unique identifier - indent(f_service_) << js_const_type_ << "args = new " << argsname << "(" << params_identifier << ");" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "(" << params_identifier << ");" << '\n'; } else { - indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << '\n'; } // Serialize the request header within try/catch - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent_up(); if (gen_node_) { f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", this.seqid());" << endl; + << "', " << messageType << ", this.seqid());" << '\n'; } else { f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", this.seqid);" << endl; + << "', " << messageType << ", this.seqid);" << '\n'; } // Write to the stream - f_service_ << indent() << "args.write(" << outputVar << ");" << endl << indent() << outputVar - << ".writeMessageEnd();" << endl; + f_service_ << indent() << "args[Symbol.for(\"write\")](" << outputVar << ");" << '\n' << indent() << outputVar + << ".writeMessageEnd();" << '\n'; if (gen_node_) { if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.flush();" << endl; - f_service_ << indent() << js_const_type_ << "callback = this._reqs[this.seqid()] || function() {};" << endl; - f_service_ << indent() << "delete this._reqs[this.seqid()];" << endl; - f_service_ << indent() << "callback(null);" << endl; + f_service_ << indent() << "this.output.flush();" << '\n'; + f_service_ << indent() << js_const_type_ << "callback = this._reqs[this.seqid()] || function() {};" << '\n'; + f_service_ << indent() << "delete this._reqs[this.seqid()];" << '\n'; + f_service_ << indent() << "callback(null);" << '\n'; } else { - f_service_ << indent() << "return this.output.flush();" << endl; + f_service_ << indent() << "return this.output.flush();" << '\n'; } } else { if (gen_jquery_) { - f_service_ << indent() << "return this.output.getTransport().flush(callback);" << endl; + f_service_ << indent() << "return this.output.getTransport().flush(callback);" << '\n'; } else if (gen_es6_) { - f_service_ << indent() << js_const_type_ << "self = this;" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n'; if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl; - f_service_ << indent() << "callback();" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, null);" << '\n'; + f_service_ << indent() << "callback();" << '\n'; } else { - f_service_ << indent() << "this.output.getTransport().flush(true, () => {" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, () => {" << '\n'; indent_up(); - f_service_ << indent() << js_let_type_ << "error = null, result = null;" << endl; - f_service_ << indent() << "try {" << endl; - f_service_ << indent() << " result = self.recv_" << funname << "();" << endl; - f_service_ << indent() << "} catch (e) {" << endl; - f_service_ << indent() << " error = e;" << endl; - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "callback(error, result);" << endl; + f_service_ << indent() << js_let_type_ << "error = null, result = null;" << '\n'; + f_service_ << indent() << "try {" << '\n'; + f_service_ << indent() << " result = self.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "} catch (e) {" << '\n'; + f_service_ << indent() << " error = e;" << '\n'; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "callback(error, result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } } else { - f_service_ << indent() << "if (callback) {" << endl; + f_service_ << indent() << "if (callback) {" << '\n'; indent_up(); if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl; - f_service_ << indent() << "callback();" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, null);" << '\n'; + f_service_ << indent() << "callback();" << '\n'; } else { - f_service_ << indent() << js_const_type_ << "self = this;" << endl; - f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n'; + f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << '\n'; indent_up(); - f_service_ << indent() << js_let_type_ << "result = null;" << endl; - f_service_ << indent() << "try {" << endl; - f_service_ << indent() << " result = self.recv_" << funname << "();" << endl; - f_service_ << indent() << "} catch (e) {" << endl; - f_service_ << indent() << " result = e;" << endl; - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "callback(result);" << endl; + f_service_ << indent() << js_let_type_ << "result = null;" << '\n'; + f_service_ << indent() << "try {" << '\n'; + f_service_ << indent() << " result = self.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "} catch (e) {" << '\n'; + f_service_ << indent() << " result = e;" << '\n'; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "callback(result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } indent_down(); - f_service_ << indent() << "} else {" << endl; - f_service_ << indent() << " return this.output.getTransport().flush();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "} else {" << '\n'; + f_service_ << indent() << " return this.output.getTransport().flush();" << '\n'; + f_service_ << indent() << "}" << '\n'; } } indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; // Reset the transport and delete registered callback if there was a serialization error - f_service_ << indent() << "catch (e) {" << endl; + f_service_ << indent() << "catch (e) {" << '\n'; indent_up(); if (gen_node_) { - f_service_ << indent() << "delete this._reqs[this.seqid()];" << endl; - f_service_ << indent() << "if (typeof " << outputVar << ".reset === 'function') {" << endl; - f_service_ << indent() << " " << outputVar << ".reset();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "delete this._reqs[this.seqid()];" << '\n'; + f_service_ << indent() << "if (typeof " << outputVar << ".reset === 'function') {" << '\n'; + f_service_ << indent() << " " << outputVar << ".reset();" << '\n'; + f_service_ << indent() << "}" << '\n'; } else { - f_service_ << indent() << "if (typeof " << outputVar << ".getTransport().reset === 'function') {" << endl; - f_service_ << indent() << " " << outputVar << ".getTransport().reset();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "if (typeof " << outputVar << ".getTransport().reset === 'function') {" << '\n'; + f_service_ << indent() << " " << outputVar << ".getTransport().reset();" << '\n'; + f_service_ << indent() << "}" << '\n'; } - f_service_ << indent() << "throw e;" << endl; + f_service_ << indent() << "throw e;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; indent_down(); // Close send function if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // Receive function @@ -2108,19 +2164,19 @@ void t_js_generator::generate_service_client(t_service* tservice) { std::string resultname = js_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_result"; - f_service_ << endl; + f_service_ << '\n'; // Open receive function if (gen_node_) { if (gen_es6_) { - indent(f_service_) << "recv_" << (*f_iter)->get_name() << " (input, mtype, rseqid) {" << endl; + indent(f_service_) << "recv_" << (*f_iter)->get_name() << " (input, mtype, rseqid) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.recv_" << (*f_iter)->get_name() - << " = function(input,mtype,rseqid) {" << endl; + << " = function(input,mtype,rseqid) {" << '\n'; } } else { if (gen_es6_) { - indent(f_service_) << "recv_" << (*f_iter)->get_name() << " () {" << endl; + indent(f_service_) << "recv_" << (*f_iter)->get_name() << " () {" << '\n'; } else { t_struct noargs(program_); @@ -2128,7 +2184,7 @@ void t_js_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype." << function_signature(&recv_function) << " {" << endl; + << "Client.prototype." << function_signature(&recv_function) << " {" << '\n'; } } @@ -2142,68 +2198,74 @@ void t_js_generator::generate_service_client(t_service* tservice) { } if (gen_node_) { - f_service_ << indent() << js_const_type_ << "callback = this._reqs[rseqid] || function() {};" << endl - << indent() << "delete this._reqs[rseqid];" << endl; + f_service_ << indent() << js_const_type_ << "callback = this._reqs[rseqid] || function() {};" << '\n' + << indent() << "delete this._reqs[rseqid];" << '\n'; } else { - f_service_ << indent() << js_const_type_ << "ret = this.input.readMessageBegin();" << endl - << indent() << js_const_type_ << "mtype = ret.mtype;" << endl; + f_service_ << indent() << js_const_type_ << "ret = this.input.readMessageBegin();" << '\n' + << indent() << js_const_type_ << "mtype = ret.mtype;" << '\n'; } - f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << endl; + f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << '\n'; indent_up(); - f_service_ << indent() << js_const_type_ << "x = new Thrift.TApplicationException();" << endl - << indent() << "x.read(" << inputVar << ");" << endl - << indent() << inputVar << ".readMessageEnd();" << endl - << indent() << render_recv_throw("x") << endl; + f_service_ << indent() << js_const_type_ << "x = new Thrift.TApplicationException();" << '\n' + << indent() << "x[Symbol.for(\"read\")](" << inputVar << ");" << '\n' + << indent() << inputVar << ".readMessageEnd();" << '\n' + << indent() << render_recv_throw("x") << '\n'; scope_down(f_service_); - f_service_ << indent() << js_const_type_ << "result = new " << resultname << "();" << endl << indent() - << "result.read(" << inputVar << ");" << endl; + f_service_ << indent() << js_const_type_ << "result = new " << resultname << "();" << '\n' << indent() + << "result[Symbol.for(\"read\")](" << inputVar << ");" << '\n'; - f_service_ << indent() << inputVar << ".readMessageEnd();" << endl << endl; + f_service_ << indent() << inputVar << ".readMessageEnd();" << '\n' << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (null !== result." << (*x_iter)->get_name() << ") {" << endl + f_service_ << indent() << "if (null !== result." << (*x_iter)->get_name() << ") {" << '\n' << indent() << " " << render_recv_throw("result." + (*x_iter)->get_name()) - << endl << indent() << "}" << endl; + << '\n' << indent() << "}" << '\n'; } // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (null !== result.success) {" << endl << indent() << " " - << render_recv_return("result.success") << endl << indent() << "}" << endl; + f_service_ << indent() << "if (null !== result.success) {" << '\n' << indent() << " " + << render_recv_return("result.success") << '\n' << indent() << "}" << '\n'; f_service_ << indent() << render_recv_throw("'" + (*f_iter)->get_name() + " failed: unknown result'") - << endl; + << '\n'; } else { if (gen_node_) { - indent(f_service_) << "callback(null);" << endl; + indent(f_service_) << "callback(null);" << '\n'; } else { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } } // Close receive function indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } } } // Finish class definitions if (gen_ts_) { - f_service_ts_ << ts_indent() << "}" << endl; + f_service_ts_ << ts_indent() << "}" << '\n'; } if (gen_es6_) { indent_down(); - f_service_ << "};" << endl; + f_service_ << "};" << '\n'; + } + + if(gen_esm_) { + f_service_ << "export { " << client_var << " as Client };" << '\n'; + } else if(gen_node_) { + f_service_ << "exports.Client = " << client_var << ";" << '\n'; } } @@ -2284,7 +2346,7 @@ void t_js_generator::generate_deserialize_field(ostream& out, out << ".value"; } - out << ";" << endl; + out << ";" << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2300,7 +2362,7 @@ void t_js_generator::generate_deserialize_field(ostream& out, */ void t_js_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << prefix << " = new " << js_type_namespace(tstruct->get_program()) - << tstruct->get_name() << "();" << endl << indent() << prefix << ".read(input);" << endl; + << tstruct->get_name() << "();" << '\n' << indent() << prefix << "[Symbol.for(\"read\")](input);" << '\n'; } void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -2311,36 +2373,36 @@ void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Declare variables, read header if (ttype->is_map()) { - out << indent() << prefix << " = {};" << endl; + out << indent() << prefix << " = {};" << '\n'; - out << indent() << js_const_type_ << rtmp3 << " = input.readMapBegin();" << endl; - out << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << js_const_type_ << rtmp3 << " = input.readMapBegin();" << '\n'; + out << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } else if (ttype->is_set()) { - out << indent() << prefix << " = [];" << endl - << indent() << js_const_type_ << rtmp3 << " = input.readSetBegin();" << endl - << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << prefix << " = [];" << '\n' + << indent() << js_const_type_ << rtmp3 << " = input.readSetBegin();" << '\n' + << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } else if (ttype->is_list()) { - out << indent() << prefix << " = [];" << endl - << indent() << js_const_type_ << rtmp3 << " = input.readListBegin();" << endl - << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << prefix << " = [];" << '\n' + << indent() << js_const_type_ << rtmp3 << " = input.readListBegin();" << '\n' + << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for (" << js_let_type_ << i << " = 0; " << i << " < " << size << "; ++" << i << ") {" << endl; + indent(out) << "for (" << js_let_type_ << i << " = 0; " << i << " < " << size << "; ++" << i << ") {" << '\n'; indent_up(); if (ttype->is_map()) { if (!gen_node_) { - out << indent() << "if (" << i << " > 0 ) {" << endl << indent() - << " if (input.rstack.length > input.rpos[input.rpos.length -1] + 1) {" << endl - << indent() << " input.rstack.pop();" << endl << indent() << " }" << endl << indent() - << "}" << endl; + out << indent() << "if (" << i << " > 0 ) {" << '\n' << indent() + << " if (input.rstack.length > input.rpos[input.rpos.length -1] + 1) {" << '\n' + << indent() << " input.rstack.pop();" << '\n' << indent() << " }" << '\n' << indent() + << "}" << '\n'; } generate_deserialize_map_element(out, (t_map*)ttype, prefix); @@ -2354,11 +2416,11 @@ void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Read container end if (ttype->is_map()) { - indent(out) << "input.readMapEnd();" << endl; + indent(out) << "input.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "input.readSetEnd();" << endl; + indent(out) << "input.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "input.readListEnd();" << endl; + indent(out) << "input.readListEnd();" << '\n'; } } @@ -2371,24 +2433,24 @@ void t_js_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, false, false) << ";" << endl; - indent(out) << declare_field(&fval, false, false) << ";" << endl; + indent(out) << declare_field(&fkey, false, false) << ";" << '\n'; + indent(out) << declare_field(&fval, false, false) << ";" << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << "[" << key << "] = " << val << ";" << endl; + indent(out) << prefix << "[" << key << "] = " << val << ";" << '\n'; } void t_js_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << js_let_type_ << elem << " = null;" << endl; + indent(out) << js_let_type_ << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push(" << elem << ");" << endl; + indent(out) << prefix << ".push(" << elem << ");" << '\n'; } void t_js_generator::generate_deserialize_list_element(ostream& out, @@ -2397,11 +2459,11 @@ void t_js_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << js_let_type_ << elem << " = null;" << endl; + indent(out) << js_let_type_ << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push(" << elem << ");" << endl; + indent(out) << prefix << ".push(" << elem << ");" << '\n'; } /** @@ -2465,7 +2527,7 @@ void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, str } else if (type->is_enum()) { out << "writeI32(" << name << ")"; } - out << ";" << endl; + out << ";" << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -2483,7 +2545,7 @@ void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, str */ void t_js_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(output);" << endl; + indent(out) << prefix << "[Symbol.for(\"write\")](output);" << '\n'; } /** @@ -2493,58 +2555,58 @@ void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, s if (ttype->is_map()) { indent(out) << "output.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "Thrift.objectLength(" << prefix << "));" << endl; + << "Thrift.objectLength(" << prefix << "));" << '\n'; } else if (ttype->is_set()) { indent(out) << "output.writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << prefix << ".length);" << endl; + << prefix << ".length);" << '\n'; } else if (ttype->is_list()) { indent(out) << "output.writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) - << ", " << prefix << ".length);" << endl; + << ", " << prefix << ".length);" << '\n'; } if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - indent(out) << "for (" << js_let_type_ << kiter << " in " << prefix << ") {" << endl; + indent(out) << "for (" << js_let_type_ << kiter << " in " << prefix << ") {" << '\n'; indent_up(); - indent(out) << "if (" << prefix << ".hasOwnProperty(" << kiter << ")) {" << endl; + indent(out) << "if (" << prefix << ".hasOwnProperty(" << kiter << ")) {" << '\n'; indent_up(); - indent(out) << js_let_type_ << viter << " = " << prefix << "[" << kiter << "];" << endl; + indent(out) << js_let_type_ << viter << " = " << prefix << "[" << kiter << "];" << '\n'; generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); scope_down(out); scope_down(out); } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl; + indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << '\n'; indent_up(); - indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl; + indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << '\n'; indent_up(); - indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl; + indent(out) << iter << " = " << prefix << "[" << iter << "];" << '\n'; generate_serialize_set_element(out, (t_set*)ttype, iter); scope_down(out); scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl; + indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << '\n'; indent_up(); - indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl; + indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << '\n'; indent_up(); - indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl; + indent(out) << iter << " = " << prefix << "[" << iter << "];" << '\n'; generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); scope_down(out); } if (ttype->is_map()) { - indent(out) << "output.writeMapEnd();" << endl; + indent(out) << "output.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "output.writeSetEnd();" << endl; + indent(out) << "output.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "output.writeListEnd();" << endl; + indent(out) << "output.writeListEnd();" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc index e91d65ad5db..3fb973a4f37 100644 --- a/compiler/cpp/src/thrift/generate/t_json_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc @@ -42,8 +42,6 @@ using std::stringstream; using std::vector; using std::stack; -static const string endl = "\n"; -static const string quot = "\""; static const bool NO_INDENT = false; static const bool FORCE_STRING = true; @@ -182,20 +180,20 @@ string t_json_generator::escape_json_string(const string& input) { } void t_json_generator::start_object(bool should_indent) { - f_json_ << (should_indent ? indent() : "") << "{" << endl; + f_json_ << (should_indent ? indent() : "") << "{" << '\n'; indent_up(); comma_needed_.push(false); } void t_json_generator::start_array() { - f_json_ << "[" << endl; + f_json_ << "[" << '\n'; indent_up(); comma_needed_.push(false); } void t_json_generator::write_comma_if_needed() { if (comma_needed_.top()) { - f_json_ << "," << endl; + f_json_ << "," << '\n'; } } @@ -230,14 +228,14 @@ void t_json_generator::write_key_and_bool(string key, bool val) { void t_json_generator::end_object() { indent_down(); - f_json_ << endl << indent() << "}"; + f_json_ << '\n' << indent() << "}"; comma_needed_.pop(); } void t_json_generator::end_array() { indent_down(); if (comma_needed_.top()) { - f_json_ << endl; + f_json_ << '\n'; } indent(f_json_) << "]"; comma_needed_.pop(); @@ -296,7 +294,7 @@ void t_json_generator::write_type_spec(t_type* ttype) { } void t_json_generator::close_generator() { - f_json_ << endl; + f_json_ << '\n'; f_json_.close(); } @@ -471,7 +469,7 @@ void t_json_generator::generate_typedef(t_typedef* ttypedef) { } void t_json_generator::write_string(const string& value) { - f_json_ << quot << escape_json_string(value) << quot; + f_json_ << '\"' << escape_json_string(value) << '\"'; } void t_json_generator::write_const_value(t_const_value* value, bool should_force_string) { @@ -537,7 +535,7 @@ void t_json_generator::write_const_value(t_const_value* value, bool should_force } string t_json_generator::json_str(const string& str) { - return quot + escape_json_string(str) + quot; + return string("\"") + escape_json_string(str) + string("\""); } void t_json_generator::generate_constant(t_const* con) { diff --git a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc index a0172720045..2e81909c48b 100644 --- a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc @@ -45,8 +45,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string KOTLIN_RESERVED_WORDS[] = { "as", "as?", "break", "class", "continue", "do", "else", "false", "for", "fun", "if", "in", "!in", "interface", @@ -209,7 +207,7 @@ void t_kotlin_generator::init_generator() { * Nothing in Kotlin generator */ void t_kotlin_generator::close_generator() { - f_types_ << endl; + f_types_ << '\n'; f_types_.close(); } @@ -222,7 +220,7 @@ void t_kotlin_generator::close_generator() { */ void t_kotlin_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << "typealias " << ttypedef->get_symbolic() << " = " - << type_name(ttypedef->get_type(), true) << endl; + << type_name(ttypedef->get_type(), true) << '\n'; } void t_kotlin_generator::generate_enum(t_enum* tenum) { @@ -241,32 +239,32 @@ void t_kotlin_generator::generate_enum(t_enum* tenum) { auto first = true; auto enum_values = tenum->get_constants(); for (auto& enum_value : enum_values) { - f_enum << (first ? "" : ",") << endl; + f_enum << (first ? "" : ",") << '\n'; first = false; indent(f_enum) << enum_value->get_name() << "(" << enum_value->get_value() << ")"; } if (first) { indent(f_enum); } - f_enum << ";" << endl << endl; - indent(f_enum) << "override fun getValue() = value" << endl << endl; + f_enum << ";" << '\n' << '\n'; + indent(f_enum) << "override fun getValue() = value" << '\n' << '\n'; { - indent(f_enum) << "companion object {" << endl; + indent(f_enum) << "companion object {" << '\n'; indent_up(); { - indent(f_enum) << "@kotlin.jvm.JvmStatic" << endl; + indent(f_enum) << "@kotlin.jvm.JvmStatic" << '\n'; indent(f_enum) << "fun findByValue(i: kotlin.Int): " << kotlin_safe_name(tenum->get_name()) - << "? {" << endl; + << "? {" << '\n'; indent_up(); { - indent(f_enum) << "return when (i) {" << endl; + indent(f_enum) << "return when (i) {" << '\n'; indent_up(); { auto enum_values = tenum->get_constants(); for (auto& enum_value : enum_values) { - indent(f_enum) << enum_value->get_value() << " -> " << enum_value->get_name() << endl; + indent(f_enum) << enum_value->get_value() << " -> " << enum_value->get_name() << '\n'; } - indent(f_enum) << "else -> null" << endl; + indent(f_enum) << "else -> null" << '\n'; } scope_down(f_enum); } @@ -322,7 +320,7 @@ void t_kotlin_generator::generate_consts(std::vector consts) { } else { // TODO } - f_types_ << endl; + f_types_ << '\n'; } } @@ -442,7 +440,7 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, t_struct* tstruct) { indent(out) << "enum class _Fields(private val thriftFieldId: kotlin.Short, private val " "fieldName: kotlin.String) : org.apache.thrift.TFieldIdEnum {" - << endl; + << '\n'; indent_up(); { // fields @@ -450,7 +448,7 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, bool first = true; for (auto& field : tstruct->get_members()) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << constant_name(field->get_name()) << "(" << field->get_key() << ", \"" @@ -459,49 +457,49 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, if (first) { indent(out); } - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; } // methods - indent(out) << "override fun getThriftFieldId() = thriftFieldId" << endl << endl; - indent(out) << "override fun getFieldName() = fieldName" << endl << endl; + indent(out) << "override fun getThriftFieldId() = thriftFieldId" << '\n' << '\n'; + indent(out) << "override fun getFieldName() = fieldName" << '\n' << '\n'; // companion object - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); { - indent(out) << "@kotlin.jvm.JvmStatic" << endl; - indent(out) << "fun findByValue(value: kotlin.Int): _Fields? {" << endl; + indent(out) << "@kotlin.jvm.JvmStatic" << '\n'; + indent(out) << "fun findByValue(value: kotlin.Int): _Fields? {" << '\n'; indent_up(); { - indent(out) << "return when (value) {" << endl; + indent(out) << "return when (value) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << field->get_key() << " -> " << constant_name(field->get_name()) << endl; + indent(out) << field->get_key() << " -> " << constant_name(field->get_name()) << '\n'; } - indent(out) << "else -> null" << endl; + indent(out) << "else -> null" << '\n'; } scope_down(out); } scope_down(out); } - out << endl; + out << '\n'; { - indent(out) << "@kotlin.jvm.JvmStatic" << endl; - indent(out) << "fun findByName(name: kotlin.String): _Fields? {" << endl; + indent(out) << "@kotlin.jvm.JvmStatic" << '\n'; + indent(out) << "fun findByName(name: kotlin.String): _Fields? {" << '\n'; indent_up(); { - indent(out) << "return when (name) {" << endl; + indent(out) << "return when (name) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { indent(out) << "\"" << field->get_name() << "\"" - << " -> " << constant_name(field->get_name()) << endl; + << " -> " << constant_name(field->get_name()) << '\n'; } - indent(out) << "else -> null" << endl; + indent(out) << "else -> null" << '\n'; } scope_down(out); } @@ -511,16 +509,16 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_struct* tstruct) { - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); { indent(out) << "private val STRUCT_DESC: org.apache.thrift.protocol.TStruct = " "org.apache.thrift.protocol.TStruct(\"" - << tstruct->get_name() << "\")" << endl; + << tstruct->get_name() << "\")" << '\n'; { for (auto& field : tstruct->get_members()) { // field desc @@ -528,15 +526,15 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s << "_FIELD_DESC: org.apache.thrift.protocol.TField = " "org.apache.thrift.protocol.TField(\"" << field->get_name() << "\", " << type_to_enum(field->get_type()) << ", " - << field->get_key() << ")" << endl; + << field->get_key() << ")" << '\n'; // field metadata indent(out) << "private val " << constant_name(field->get_name()) << "_FIELD_META_DATA: org.apache.thrift.meta_data.FieldMetaData = " "org.apache.thrift.meta_data.FieldMetaData(" - << endl; + << '\n'; indent_up(); { - indent(out) << '"' << field->get_name() << '"' << ',' << endl; + indent(out) << '"' << field->get_name() << '"' << ',' << '\n'; indent(out) << "org.apache.thrift.TFieldRequirementType."; if (field->get_req() == t_field::T_REQUIRED) { out << "REQUIRED"; @@ -545,12 +543,12 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s } else { out << "DEFAULT"; } - out << ',' << endl; + out << ',' << '\n'; generate_field_value_meta_data(indent(out), field->get_type()); - out << ',' << endl; + out << ',' << '\n'; generate_metadata_for_field_annotations(indent(out), field); } - out << ")" << endl; + out << ")" << '\n'; indent_down(); } } @@ -558,23 +556,23 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s // all fields in a map indent(out) << "private val metadata: Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> = mapOf(" - << endl; + << '\n'; indent_up(); for (auto& field : tstruct->get_members()) { indent(out) << "_Fields." << constant_name(field->get_name()) << " to " - << constant_name(field->get_name()) << "_FIELD_META_DATA," << endl; + << constant_name(field->get_name()) << "_FIELD_META_DATA," << '\n'; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; - indent(out) << "init {" << endl; + indent(out) << "init {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(" - << tstruct->get_name() << "::class.java, metadata)" << endl; + << tstruct->get_name() << "::class.java, metadata)" << '\n'; scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_metadata_for_field_annotations(std::ostream& out, @@ -582,10 +580,10 @@ void t_kotlin_generator::generate_metadata_for_field_annotations(std::ostream& o if (field->annotations_.size() == 0) { out << "emptyMap()"; } else { - out << "mapOf(" << endl; + out << "mapOf(" << '\n'; indent_up(); for (auto& annotation : field->annotations_) { - indent(out) << "\"" + annotation.first + "\" to \"" + annotation.second.back() + "\"," << endl; + indent(out) << "\"" + annotation.first + "\" to \"" + annotation.second.back() + "\"," << '\n'; } indent_down(); indent(out) << ")"; @@ -600,24 +598,24 @@ void t_kotlin_generator::generate_field_value_meta_data(std::ostream& out, t_typ out << "StructMetaData(" << ttype_class << "STRUCT, " << type_name(type) << "::class.java"; } else if (type->is_container()) { if (type->is_list()) { - out << "ListMetaData(" << ttype_class << "LIST," << endl; + out << "ListMetaData(" << ttype_class << "LIST," << '\n'; indent_up(); t_type* elem_type = ((t_list*)type)->get_elem_type(); generate_field_value_meta_data(indent(out), elem_type); indent_down(); } else if (type->is_set()) { - out << "SetMetaData(" << ttype_class << "SET," << endl; + out << "SetMetaData(" << ttype_class << "SET," << '\n'; indent_up(); t_type* elem_type = ((t_set*)type)->get_elem_type(); generate_field_value_meta_data(indent(out), elem_type); indent_down(); } else { - out << "MapMetaData(" << ttype_class << "MAP," << endl; + out << "MapMetaData(" << ttype_class << "MAP," << '\n'; indent_up(); t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); generate_field_value_meta_data(indent(out), key_type); - out << "," << endl; + out << "," << '\n'; generate_field_value_meta_data(indent(out), val_type); indent_down(); } @@ -635,30 +633,30 @@ void t_kotlin_generator::generate_field_value_meta_data(std::ostream& out, t_typ } void t_kotlin_generator::generate_struct_method_deep_copy(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun deepCopy(): " << tstruct->get_name() << " {" << endl; + indent(out) << "override fun deepCopy(): " << tstruct->get_name() << " {" << '\n'; indent_up(); { - indent(out) << "return " << tstruct->get_name() << " (" << endl; + indent(out) << "return " << tstruct->get_name() << " (" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << kotlin_safe_name(field->get_name()) << "," << endl; + indent(out) << kotlin_safe_name(field->get_name()) << "," << '\n'; } } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_compare_to(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun compareTo(other: " << tstruct->get_name() << "?): kotlin.Int {" - << endl; + << '\n'; indent_up(); { indent(out) << "val comparator = compareBy<" << tstruct->get_name() - << "> { it::class.java.name }" << endl; + << "> { it::class.java.name }" << '\n'; indent_up(); for (auto& field : tstruct->get_members()) { indent(out) << ".thenBy"; @@ -667,33 +665,33 @@ void t_kotlin_generator::generate_struct_method_compare_to(std::ostream& out, t_ || field_type->is_binary()) { out << "(org.apache.thrift.TBaseHelper::compareTo)"; } - out << " { it." << kotlin_safe_name(field->get_name()) << " } " << endl; + out << " { it." << kotlin_safe_name(field->get_name()) << " } " << '\n'; } indent_down(); - indent(out) << "return nullsFirst(comparator).compare(this, other)" << endl; + indent(out) << "return nullsFirst(comparator).compare(this, other)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_field_for_id(std::ostream& out, t_struct* /*tstruct*/) { - indent(out) << "override fun fieldForId(fieldId: kotlin.Int): _Fields {" << endl; + indent(out) << "override fun fieldForId(fieldId: kotlin.Int): _Fields {" << '\n'; indent_up(); { indent(out) << "return _Fields.findByValue(fieldId) ?: throw " "kotlin.IllegalArgumentException(\"invalid fieldId $fieldId\")" - << endl; + << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_is_set(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun isSet(field: _Fields): kotlin.Boolean {" << endl; + indent(out) << "override fun isSet(field: _Fields): kotlin.Boolean {" << '\n'; indent_up(); { - indent(out) << "return when (field) {" << endl; + indent(out) << "return when (field) {" << '\n'; indent_up(); { auto members = tstruct->get_members(); @@ -705,67 +703,67 @@ void t_kotlin_generator::generate_struct_method_is_set(std::ostream& out, t_stru } else { out << "this." << kotlin_safe_name(field->get_name()) << " != null"; } - out << endl; + out << '\n'; } } else { - indent(out) << "else -> false" << endl; + indent(out) << "else -> false" << '\n'; } } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun clear(): kotlin.Unit {" << endl; + indent(out) << "override fun clear(): kotlin.Unit {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { auto is_required = field->get_req() == t_field::T_REQUIRED; indent(out) << (is_required ? "_" + field->get_name() : kotlin_safe_name(field->get_name())) - << " = null" << endl; + << " = null" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_validate(std::ostream& out, t_struct* tstruct) { - indent(out) << "@kotlin.jvm.Throws(org.apache.thrift.TException::class)" << endl; - indent(out) << "fun validate(): kotlin.Unit {" << endl; + indent(out) << "@kotlin.jvm.Throws(org.apache.thrift.TException::class)" << '\n'; + indent(out) << "fun validate(): kotlin.Unit {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { bool is_required = field->get_req() == t_field::T_REQUIRED; if (is_required) { - indent(out) << "if (_" << field->get_name() << " == null) {" << endl; + indent(out) << "if (_" << field->get_name() << " == null) {" << '\n'; indent_up(); { indent(out) << "throw org.apache.thrift.TException(\"Required field `" << field->get_name() << "' is null, " "struct is: $this\")" - << endl; + << '\n'; } scope_down(out); } } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_set_field_value(std::ostream& out, t_struct* tstruct) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; indent(out) << "override fun setFieldValue(field: _Fields, value: kotlin.Any?): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { const vector& members = tstruct->get_members(); if (members.size() > 0) { - indent(out) << "when (field) {" << endl; + indent(out) << "when (field) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { @@ -773,155 +771,155 @@ void t_kotlin_generator::generate_struct_method_set_field_value(std::ostream& ou indent(out) << "_Fields." << constant_name(field->get_name()) << " -> this." << (is_required ? "_" + field->get_name() : kotlin_safe_name(field->get_name())) - << " = value as " << type_name(field->get_type()) << "?" << endl; + << " = value as " << type_name(field->get_type()) << "?" << '\n'; } } scope_down(out); } else { - indent(out) << "return" << endl; + indent(out) << "return" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_get_field_value(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun getFieldValue(field: _Fields): kotlin.Any? {" << endl; + indent(out) << "override fun getFieldValue(field: _Fields): kotlin.Any? {" << '\n'; indent_up(); { auto members = tstruct->get_members(); if (members.size() > 0) { - indent(out) << "return when (field) {" << endl; + indent(out) << "return when (field) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { indent(out) << "_Fields." << constant_name(field->get_name()) << " -> this." - << kotlin_safe_name(field->get_name()) << endl; + << kotlin_safe_name(field->get_name()) << '\n'; } } scope_down(out); } else { - indent(out) << "return null" << endl; + indent(out) << "return null" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_read(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun read(iproto: org.apache.thrift.protocol.TProtocol): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { indent(out) << "require(org.apache.thrift.scheme.StandardScheme::class.java == iproto.scheme) { " "\"only standard scheme is " "supported for now\" }" - << endl; - indent(out) << tstruct->get_name() << "StandardScheme.read(iproto, this)" << endl; + << '\n'; + indent(out) << tstruct->get_name() << "StandardScheme.read(iproto, this)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_write(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun write(oproto: org.apache.thrift.protocol.TProtocol): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { indent(out) << "require(org.apache.thrift.scheme.StandardScheme::class.java == oproto.scheme) { " "\"only standard scheme is " "supported for now\" }" - << endl; - indent(out) << tstruct->get_name() << "StandardScheme.write(oproto, this)" << endl; + << '\n'; + indent(out) << tstruct->get_name() << "StandardScheme.write(oproto, this)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme_read(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun read(iproto: org.apache.thrift.protocol.TProtocol, struct: " - << tstruct->get_name() << ") {" << endl; + << tstruct->get_name() << ") {" << '\n'; indent_up(); { - indent(out) << "iproto.apply {" << endl; + indent(out) << "iproto.apply {" << '\n'; indent_up(); { - indent(out) << "readStruct {" << endl; + indent(out) << "readStruct {" << '\n'; indent_up(); { - indent(out) << "var stopped = false" << endl; - indent(out) << "while (!stopped) {" << endl; + indent(out) << "var stopped = false" << '\n'; + indent(out) << "while (!stopped) {" << '\n'; indent_up(); { - indent(out) << "stopped = readField {" << endl; + indent(out) << "stopped = readField {" << '\n'; indent_up(); { indent(out) << "val skipNext = { " "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, it.type) }" - << endl; + << '\n'; - indent(out) << "when (it.id.toInt()) {" << endl; + indent(out) << "when (it.id.toInt()) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << field->get_key() << " -> {" << endl; + indent(out) << field->get_key() << " -> {" << '\n'; indent_up(); { indent(out) << "if (it.type == " << type_to_enum(field->get_type()) << ") {" - << endl; + << '\n'; indent_up(); generate_deserialize_field(out, field, "struct."); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "skipNext()" << endl; + indent(out) << "skipNext()" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } scope_down(out); } - indent(out) << "else -> skipNext()" << endl; + indent(out) << "else -> skipNext()" << '\n'; } scope_down(out); } scope_down(out); } scope_down(out); - indent(out) << "struct.validate()" << endl; + indent(out) << "struct.validate()" << '\n'; } scope_down(out); } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme_write(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun write(oproto: org.apache.thrift.protocol.TProtocol, struct: " - << tstruct->get_name() << ") {" << endl; + << tstruct->get_name() << ") {" << '\n'; indent_up(); { - indent(out) << "struct.validate()" << endl; - indent(out) << "oproto.apply {" << endl; + indent(out) << "struct.validate()" << '\n'; + indent(out) << "oproto.apply {" << '\n'; indent_up(); { - indent(out) << "writeStruct(STRUCT_DESC) {" << endl; + indent(out) << "writeStruct(STRUCT_DESC) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { auto is_required = field->get_req() == t_field::T_REQUIRED; indent(out) << "struct." << kotlin_safe_name(field->get_name()) << (is_required ? "" : "?") << ".let { " - << kotlin_safe_name(field->get_name()) << " ->" << endl; + << kotlin_safe_name(field->get_name()) << " ->" << '\n'; indent_up(); { indent(out) << "writeField(" << constant_name(field->get_name()) << "_FIELD_DESC) {" - << endl; + << '\n'; indent_up(); generate_serialize_field(out, field); scope_down(out); @@ -929,36 +927,36 @@ void t_kotlin_generator::generate_struct_standard_scheme_write(std::ostream& out scope_down(out); } } - indent(out) << "writeFieldStop()" << endl; + indent(out) << "writeFieldStop()" << '\n'; scope_down(out); } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme(std::ostream& out, t_struct* tstruct) { indent(out) << "private object " << tstruct->get_name() << "StandardScheme : org.apache.thrift.scheme.StandardScheme<" << tstruct->get_name() - << ">() {" << endl; + << ">() {" << '\n'; indent_up(); generate_struct_standard_scheme_read(out, tstruct); generate_struct_standard_scheme_write(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_union_tuple_scheme(std::ostream& out, t_struct* /*tunion*/) { indent(out) << "override fun tupleSchemeReadValue(iproto: org.apache.thrift.protocol.TProtocol, " "fieldID: kotlin.Short) = throw kotlin.UnsupportedOperationException(\"only " "standard scheme is supported for now\")" - << endl; + << '\n'; indent(out) << "override fun tupleSchemeWriteValue(oproto: org.apache.thrift.protocol.TProtocol) = " "throw kotlin.UnsupportedOperationException(\"only standard scheme is supported for " "now\")" - << endl; + << '\n'; } void t_kotlin_generator::generate_union_standard_scheme(std::ostream& out, t_struct* tunion) { @@ -970,61 +968,61 @@ void t_kotlin_generator::generate_union_standard_scheme_read(std::ostream& out, indent(out) << "override fun standardSchemeReadValue(iproto: org.apache.thrift.protocol.TProtocol, " "field: org.apache.thrift.protocol.TField): Any? =" - << endl; + << '\n'; indent_up(); - indent(out) << "when (_Fields.findByValue(field.id.toInt())) {" << endl; + indent(out) << "when (_Fields.findByValue(field.id.toInt())) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { auto expect_type = type_name(member->get_type()); - indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << endl; + indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << '\n'; indent_up(); { indent(out) << "if (field.type == " << constant_name(member->get_name()) - << "_FIELD_DESC.type) {" << endl; + << "_FIELD_DESC.type) {" << '\n'; indent_up(); - indent(out) << "iproto.run {" << endl; + indent(out) << "iproto.run {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, member->get_type()); - out << endl; + out << '\n'; scope_down(out); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << endl; - indent(out) << "null" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << '\n'; + indent(out) << "null" << '\n'; scope_down(out); } scope_down(out); } - indent(out) << "null -> {" << endl; + indent(out) << "null -> {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << endl; - indent(out) << "null" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << '\n'; + indent(out) << "null" << '\n'; scope_down(out); scope_down(out); indent_down(); } void t_kotlin_generator::generate_union_standard_scheme_write(std::ostream& out, t_struct* tunion) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; indent(out) << "override fun standardSchemeWriteValue(oproto: org.apache.thrift.protocol.TProtocol) {" - << endl; + << '\n'; indent_up(); - indent(out) << "when (setField_) {" << endl; + indent(out) << "when (setField_) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { - indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << endl; + indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << '\n'; indent_up(); { - indent(out) << "val it = value_ as " << type_name(member->get_type()) << endl; - indent(out) << "oproto.apply {" << endl; + indent(out) << "val it = value_ as " << type_name(member->get_type()) << '\n'; + indent(out) << "oproto.apply {" << '\n'; indent_up(); { indent(out); generate_serialize_value(out, member->get_type()); - out << endl; + out << '\n'; } scope_down(out); } @@ -1032,7 +1030,7 @@ void t_kotlin_generator::generate_union_standard_scheme_write(std::ostream& out, } indent(out) << "null -> throw kotlin.IllegalStateException(\"Cannot write union with unknown " "field $setField_\")" - << endl; + << '\n'; scope_down(out); scope_down(out); } @@ -1052,25 +1050,25 @@ void t_kotlin_generator::generate_union_methods_definitions(std::ostream& out, t } auto union_class_name = kotlin_safe_name(tunion->get_name()); - { indent(out) << "override fun deepCopy() = " << union_class_name << "(this)" << endl; } - { indent(out) << "override fun enumForId(id: kotlin.Short) = fieldForId(id.toInt())" << endl; } - { indent(out) << "override fun getStructDesc() = STRUCT_DESC" << endl; } + { indent(out) << "override fun deepCopy() = " << union_class_name << "(this)" << '\n'; } + { indent(out) << "override fun enumForId(id: kotlin.Short) = fieldForId(id.toInt())" << '\n'; } + { indent(out) << "override fun getStructDesc() = STRUCT_DESC" << '\n'; } { - indent(out) << "override fun getFieldDesc(setField: _Fields) = when (setField) {" << endl; + indent(out) << "override fun getFieldDesc(setField: _Fields) = when (setField) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { indent(out) << "_Fields." << constant_name(member->get_name()) << " -> " - << constant_name(member->get_name()) << "_FIELD_DESC" << endl; + << constant_name(member->get_name()) << "_FIELD_DESC" << '\n'; } scope_down(out); } } void t_kotlin_generator::generate_union_method_check_type(std::ostream& out, t_struct* tunion) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; - indent(out) << "override fun checkType(setField: _Fields, value: kotlin.Any?) {" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; + indent(out) << "override fun checkType(setField: _Fields, value: kotlin.Any?) {" << '\n'; indent_up(); - indent(out) << "when (setField) {" << endl; + indent(out) << "when (setField) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { auto expect_type = type_name(member->get_type()); @@ -1078,7 +1076,7 @@ void t_kotlin_generator::generate_union_method_check_type(std::ostream& out, t_s << expect_type << " ?: throw kotlin.ClassCastException(\"Was expecting value of type `" << expect_type << "' for field `" << member->get_name() - << "', but got ${value?.javaClass}\")" << endl; + << "', but got ${value?.javaClass}\")" << '\n'; } scope_down(out); scope_down(out); @@ -1089,12 +1087,12 @@ void t_kotlin_generator::generate_union_definition(std::ostream& out, string /*additional interface*/) { auto union_class_name = kotlin_safe_name(tunion->get_name()); indent(out) << "class " << union_class_name << " : org.apache.thrift.TUnion<" << union_class_name - << ", " << union_class_name << "._Fields> {" << endl; + << ", " << union_class_name << "._Fields> {" << '\n'; indent_up(); indent(out) << "constructor(setField: _Fields, value: kotlin.Any) : super(setField, value)" - << endl; - indent(out) << "constructor(other: " << union_class_name << ") : super(other)" << endl; - indent(out) << "constructor() : super()" << endl; + << '\n'; + indent(out) << "constructor(other: " << union_class_name << ") : super(other)" << '\n'; + indent(out) << "constructor() : super()" << '\n'; generate_struct_field_name_constants(out, tunion); generate_struct_companion_object(out, tunion); @@ -1104,7 +1102,7 @@ void t_kotlin_generator::generate_union_definition(std::ostream& out, generate_union_standard_scheme(out, tunion); generate_union_tuple_scheme(out, tunion); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_kotlin_generator::generate_struct_definition(std::ostream& out, @@ -1123,7 +1121,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, indent_up(); auto sep = ""; for (auto field : members) { - out << sep << endl; + out << sep << '\n'; sep = ","; generate_kdoc_comment(out, field); auto is_required = field->get_req() == t_field::T_REQUIRED; @@ -1141,7 +1139,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, out << ": " << type_name(field->get_type()) << "? = null"; } indent_down(); - out << endl; + out << '\n'; indent(out) << ") : "; if (is_exception) { out << "org.apache.thrift.TException(), "; @@ -1150,7 +1148,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, additional_interface = ", " + additional_interface; } out << "org.apache.thrift.TBase<" << tstruct->get_name() << ", " << tstruct->get_name() - << "._Fields>" << additional_interface << " {" << endl; + << "._Fields>" << additional_interface << " {" << '\n'; indent_up(); @@ -1162,7 +1160,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, out << "override "; } out << "val " << kotlin_safe_name(field->get_name()) << ": " << type_name(field->get_type()) - << " get() = _" + kotlin_safe_name(field->get_name()) << "!!" << endl; + << " get() = _" + kotlin_safe_name(field->get_name()) << "!!" << '\n'; } } @@ -1181,7 +1179,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, generate_struct_method_write(out, tstruct); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } string t_kotlin_generator::base_type_write_expression(t_base_type* tbase, string it) { @@ -1286,7 +1284,7 @@ void t_kotlin_generator::generate_serialize_field(ostream& out, t_field* tfield) } indent(out); generate_serialize_value(out, type, kotlin_safe_name(tfield->get_name())); - out << endl; + out << '\n'; } /** @@ -1305,7 +1303,7 @@ void t_kotlin_generator::generate_deserialize_field(ostream& out, t_field* tfiel = prefix + (is_required ? "_" + tfield->get_name() : kotlin_safe_name(tfield->get_name())); indent(out) << name << " = "; generate_deserialize_value(out, type); - out << endl; + out << '\n'; } /** @@ -1315,33 +1313,33 @@ void t_kotlin_generator::generate_serialize_container(ostream& out, t_type* ttyp if (ttype->is_map()) { out << "writeMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << it << ") { (key, value) ->" - << endl; + << '\n'; indent_up(); { generate_serialize_value(indent(out), ((t_map*)ttype)->get_key_type(), "key"); - out << endl; + out << '\n'; generate_serialize_value(indent(out), ((t_map*)ttype)->get_val_type(), "value"); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; } else if (ttype->is_set()) { out << "writeSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << it << ") {" - << endl; + << '\n'; indent_up(); { generate_serialize_value(indent(out), ((t_set*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; } else if (ttype->is_list()) { out << "writeList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << it << ") {" - << endl; + << '\n'; { indent_up(); generate_serialize_value(indent(out), ((t_list*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; @@ -1355,41 +1353,41 @@ void t_kotlin_generator::generate_serialize_container(ostream& out, t_type* ttyp */ void t_kotlin_generator::generate_deserialize_container(ostream& out, t_type* ttype) { if (ttype->is_map()) { - out << "readMap { tmap ->" << endl; + out << "readMap { tmap ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tmap.size) {" << endl; + indent(out) << "kotlin.collections.List(tmap.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_map*)ttype)->get_key_type()); out << " to "; generate_deserialize_value(out, ((t_map*)ttype)->get_val_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}.associate { it }" << endl; + indent(out) << "}.associate { it }" << '\n'; indent_down(); indent(out) << "}"; } else if (ttype->is_set()) { - out << "readSet { tset ->" << endl; + out << "readSet { tset ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tset.size) {" << endl; + indent(out) << "kotlin.collections.List(tset.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_set*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}.toSet()" << endl; + indent(out) << "}.toSet()" << '\n'; indent_down(); indent(out) << "}"; } else if (ttype->is_list()) { - out << "readList { tlist ->" << endl; + out << "readList { tlist ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tlist.size) {" << endl; + indent(out) << "kotlin.collections.List(tlist.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_list*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); indent(out) << "}"; } else { @@ -1419,14 +1417,14 @@ void t_kotlin_generator::generate_service_interface(t_service* tservice) { ofstream_with_content_based_conditional_update out; out.open(f_service_name.c_str()); out << autogen_comment() << kotlin_package(); - out << "interface " << tservice->get_name() << " {" << endl; + out << "interface " << tservice->get_name() << " {" << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { generate_kdoc_comment(out, tfunc); - indent(out) << function_signature(tfunc) << endl; + indent(out) << function_signature(tfunc) << '\n'; } scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1437,22 +1435,22 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); generate_docstring_comment(out, "/**\n", " * ", "client implementation for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "class " << tservice->get_name() << "Client(" << endl; + indent(out) << "class " << tservice->get_name() << "Client(" << '\n'; indent_up(); - indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << endl; - indent(out) << "clientManager: org.apache.thrift.async.TAsyncClientManager," << endl; - indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport" << endl; + indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << '\n'; + indent(out) << "clientManager: org.apache.thrift.async.TAsyncClientManager," << '\n'; + indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport" << '\n'; indent_down(); out << "): org.apache.thrift.async.TAsyncClient(protocolFactory, clientManager, transport), " - << tservice->get_name() << " {" << endl - << endl; + << tservice->get_name() << " {" << '\n' + << '\n'; indent_up(); { - indent(out) << "private val seqId = java.util.concurrent.atomic.AtomicInteger()" << endl - << endl; + indent(out) << "private val seqId = java.util.concurrent.atomic.AtomicInteger()" << '\n' + << '\n'; for (auto tfunc : tservice->get_functions()) { - indent(out) << "override " << function_signature(tfunc) << " {" << endl; + indent(out) << "override " << function_signature(tfunc) << " {" << '\n'; indent_up(); { string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; @@ -1465,16 +1463,16 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { first = false; out << tfield->get_name(); } - out << ")" << endl; - indent(out) << "return transformCallback {" << endl; + out << ")" << '\n'; + indent(out) << "return transformCallback {" << '\n'; indent_up(); { - indent(out) << "checkReady()" << endl; + indent(out) << "checkReady()" << '\n'; indent(out) << "___currentMethod = ProcessCall." << tfunc->get_name() << "Call(args, seqId.getAndIncrement(), this, ___protocolFactory, ___transport, it)" - << endl; - indent(out) << "___manager.call(___currentMethod)" << endl; + << '\n'; + indent(out) << "___manager.call(___currentMethod)" << '\n'; } scope_down(out); } @@ -1484,22 +1482,22 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { indent(out) << "private suspend fun " "org.apache.thrift.async.TAsyncClient.transformCallback(action: " "(org.apache.thrift.async.AsyncMethodCallback) -> Unit): R {" - << endl; + << '\n'; indent_up(); - indent(out) << "val deferred = kotlinx.coroutines.CompletableDeferred()" << endl; + indent(out) << "val deferred = kotlinx.coroutines.CompletableDeferred()" << '\n'; indent(out) << "val callback = object : org.apache.thrift.async.AsyncMethodCallback {" - << endl; + << '\n'; indent_up(); - indent(out) << "override fun onComplete(response: R) { deferred.complete(response) }" << endl; + indent(out) << "override fun onComplete(response: R) { deferred.complete(response) }" << '\n'; indent(out) << "override fun onError(exception: java.lang.Exception) { " "deferred.completeExceptionally(exception) }" - << endl; + << '\n'; scope_down(out); - indent(out) << "action(callback)" << endl; - indent(out) << "return deferred.await()" << endl; + indent(out) << "action(callback)" << '\n'; + indent(out) << "return deferred.await()" << '\n'; scope_down(out); - indent(out) << "sealed interface ProcessCall {" << endl; + indent(out) << "sealed interface ProcessCall {" << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { generate_client_call(out, tservice, tfunc); @@ -1507,7 +1505,7 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { scope_down(out); } scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1518,74 +1516,74 @@ void t_kotlin_generator::generate_client_call(std::ostream& out, string funclassname = funname + "Call"; string rtype = type_name(tfunc->get_returntype(), true); - indent(out) << "class " + funclassname + "(" << endl; + indent(out) << "class " + funclassname + "(" << '\n'; indent_up(); string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; - indent(out) << "val args: " << args_name << "," << endl; - indent(out) << "val seqId: kotlin.Int," << endl; - indent(out) << "client: org.apache.thrift.async.TAsyncClient," << endl; - indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << endl; - indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport," << endl; + indent(out) << "val args: " << args_name << "," << '\n'; + indent(out) << "val seqId: kotlin.Int," << '\n'; + indent(out) << "client: org.apache.thrift.async.TAsyncClient," << '\n'; + indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << '\n'; + indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport," << '\n'; indent(out) << "resultHandler: org.apache.thrift.async.AsyncMethodCallback<" << rtype << ">," - << endl; + << '\n'; indent_down(); indent(out) << ") : org.apache.thrift.async.TAsyncMethodCall<" << rtype << ">(client, protocolFactory, transport, resultHandler, " - << (tfunc->is_oneway() ? "true" : "false") << "), ProcessCall {" << endl; + << (tfunc->is_oneway() ? "true" : "false") << "), ProcessCall {" << '\n'; indent_up(); indent(out) << "override fun write_args(protocol: org.apache.thrift.protocol.TProtocol) {" - << endl; + << '\n'; indent_up(); indent(out) << "val marker = org.apache.thrift.protocol.TMessage(\"" << tfunc->get_name() - << "\", org.apache.thrift.protocol.TMessageType.CALL, seqId)" << endl; - indent(out) << "protocol.writeMessage(marker) { args.write(protocol) }" << endl; + << "\", org.apache.thrift.protocol.TMessageType.CALL, seqId)" << '\n'; + indent(out) << "protocol.writeMessage(marker) { args.write(protocol) }" << '\n'; scope_down(out); - indent(out) << "override fun getResult(): " << rtype << " {" << endl; + indent(out) << "override fun getResult(): " << rtype << " {" << '\n'; indent_up(); indent(out) << "check(state == org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) { " "\"Method call not finished!\" }" - << endl; + << '\n'; indent(out) << "val memoryTransport = " "org.apache.thrift.transport.TMemoryInputTransport(frameBuffer.array())" - << endl; - indent(out) << "val protocol = client.protocolFactory.getProtocol(memoryTransport)" << endl; + << '\n'; + indent(out) << "val protocol = client.protocolFactory.getProtocol(memoryTransport)" << '\n'; if (tfunc->is_oneway()) { - indent(out) << "// one way function, nothing to read" << endl; + indent(out) << "// one way function, nothing to read" << '\n'; } else { - indent(out) << "return protocol.readMessage {" << endl; + indent(out) << "return protocol.readMessage {" << '\n'; indent_up(); { - indent(out) << "if (it.type == org.apache.thrift.protocol.TMessageType.EXCEPTION) {" << endl; + indent(out) << "if (it.type == org.apache.thrift.protocol.TMessageType.EXCEPTION) {" << '\n'; indent_up(); indent(out) << "val ex = org.apache.thrift.TApplicationException().apply { read(protocol) }" - << endl; - indent(out) << "throw ex" << endl; + << '\n'; + indent(out) << "throw ex" << '\n'; scope_down(out); - indent(out) << "if (it.seqid != seqId) {" << endl; + indent(out) << "if (it.seqid != seqId) {" << '\n'; indent_up(); - indent(out) << "throw org.apache.thrift.TApplicationException(" << endl; + indent(out) << "throw org.apache.thrift.TApplicationException(" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.TApplicationException.BAD_SEQUENCE_ID," << endl; + indent(out) << "org.apache.thrift.TApplicationException.BAD_SEQUENCE_ID," << '\n'; indent(out) << "\"" << funname << " failed: out of sequence response: expected $seqId but got ${it.seqid}\"" - << endl; + << '\n'; indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; scope_down(out); string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "().apply { read(protocol) }" << endl; + indent(out) << "val result = " << result_name << "().apply { read(protocol) }" << '\n'; for (auto xception : tfunc->get_xceptions()->get_members()) { - indent(out) << "result." << xception->get_name() << "?.let { throw it }" << endl; + indent(out) << "result." << xception->get_name() << "?.let { throw it }" << '\n'; } if (!tfunc->get_returntype()->is_void()) { indent(out) << "result.success ?: throw " "org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException." "MISSING_RESULT, \"returnString failed: unknown result\")" - << endl; + << '\n'; } } scope_down(out); @@ -1601,43 +1599,43 @@ void t_kotlin_generator::generate_service_processor(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); auto service_imports = {"import kotlinx.coroutines.future.future"}; for (auto service_import : service_imports) { - out << service_import << endl; + out << service_import << '\n'; } - out << endl; + out << '\n'; generate_docstring_comment(out, "/**\n", " * ", "server implementation for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "class " << tservice->get_name() << "Processor(" << endl; + indent(out) << "class " << tservice->get_name() << "Processor(" << '\n'; indent_up(); - indent(out) << "handler: " << tservice->get_name() << "," << endl; - indent(out) << "private val scope: kotlinx.coroutines.CoroutineScope," << endl; + indent(out) << "handler: " << tservice->get_name() << "," << '\n'; + indent(out) << "private val scope: kotlinx.coroutines.CoroutineScope," << '\n'; indent(out) << "private val processMap: kotlin.collections.Mapget_name() << ", out org.apache.thrift.TBase<*, " - "*>, out kotlin.Any>> = mapOf(" - << endl; + "*>, out kotlin.Any, out org.apache.thrift.TBase<*, *>>> = mapOf(" + << '\n'; indent_up(); { for (auto tfunc : tservice->get_functions()) { indent(out) << '"' << tfunc->get_name() << '"' << " to ProcessFunction." << tfunc->get_name() - << "(scope)," << endl; + << "(scope)," << '\n'; } } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; indent_down(); out << "): org.apache.thrift.TBaseAsyncProcessor<" << tservice->get_name() - << ">(handler, processMap) {" << endl; + << ">(handler, processMap) {" << '\n'; indent_up(); - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); indent(out) << "internal val logger: org.slf4j.Logger = " "org.slf4j.LoggerFactory.getLogger(" - << tservice->get_name() << "Processor::class.java)" << endl; + << tservice->get_name() << "Processor::class.java)" << '\n'; scope_down(out); - indent(out) << "sealed interface ProcessFunction {" << endl; + indent(out) << "sealed interface ProcessFunction {" << '\n'; indent_up(); { @@ -1647,7 +1645,7 @@ void t_kotlin_generator::generate_service_processor(t_service* tservice) { } scope_down(out); scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1656,21 +1654,32 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, t_function* tfunc) { string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; string rtype = type_name(tfunc->get_returntype(), true); + string resultname = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; indent(out) << "class " << tfunc->get_name() << "get_name() << ">(private val scope: kotlinx.coroutines.CoroutineScope) : " "org.apache.thrift.AsyncProcessFunction(\"" << tfunc->get_name() - << "\"), ProcessFunction {" << endl; + << args_name << ", " << rtype << ", " + << (tfunc->is_oneway() ? "org.apache.thrift.TBase<*, *>" : resultname) + << ">(\"" << tfunc->get_name() << "\"), ProcessFunction {" + << '\n'; indent_up(); { - indent(out) << "override fun isOneway() = " << (tfunc->is_oneway() ? "true" : "false") << endl; - indent(out) << "override fun getEmptyArgsInstance() = " << args_name << "()" << endl; + indent(out) << "override fun isOneway() = " << (tfunc->is_oneway() ? "true" : "false") << '\n'; + indent(out) << "override fun getEmptyArgsInstance() = " << args_name << "()" << '\n'; + indent(out) << "override fun getEmptyResultInstance() = "; + if (tfunc->is_oneway()) { + out << "null" << '\n'; + } + else { + out << resultname << "()" << '\n'; + } + indent(out) << '\n'; indent(out) << "override fun start(iface: I, args: " << args_name << ", resultHandler: org.apache.thrift.async.AsyncMethodCallback<" << rtype - << ">) {" << endl; + << ">) {" << '\n'; indent_up(); - indent(out) << "scope.future {" << endl; + indent(out) << "scope.future {" << '\n'; indent_up(); indent(out) << "iface." << tfunc->get_name() << "("; { @@ -1685,18 +1694,18 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, out << "args." << tfield->get_name() << "!!"; } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "}.whenComplete { r, t ->" << endl; + indent(out) << "}.whenComplete { r, t ->" << '\n'; { indent_up(); - indent(out) << "if (t != null) {" << endl; + indent(out) << "if (t != null) {" << '\n'; indent_up(); - indent(out) << "resultHandler.onError(t as java.lang.Exception)" << endl; + indent(out) << "resultHandler.onError(t as java.lang.Exception)" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "resultHandler.onComplete(r)" << endl; + indent(out) << "resultHandler.onComplete(r)" << '\n'; } scope_down(out); scope_down(out); @@ -1705,106 +1714,106 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, indent(out) << "override fun getResultHandler(fb: " "org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer, seqid: " "Int) =" - << endl; + << '\n'; indent_up(); { indent(out) << "object : org.apache.thrift.async.AsyncMethodCallback<" << rtype << ">{" - << endl; + << '\n'; indent_up(); { - indent(out) << "override fun onComplete(response: " << rtype << ") {" << endl; + indent(out) << "override fun onComplete(response: " << rtype << ") {" << '\n'; indent_up(); if (tfunc->is_oneway()) { - indent(out) << "// one way function, no result handling" << endl; + indent(out) << "// one way function, no result handling" << '\n'; } else { string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "()" << endl; + indent(out) << "val result = " << result_name << "()" << '\n'; if (!tfunc->get_returntype()->is_void()) { - indent(out) << "result.success = response" << endl; + indent(out) << "result.success = response" << '\n'; } - indent(out) << "try {" << endl; + indent(out) << "try {" << '\n'; indent_up(); indent(out) << "sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY, seqid)" - << endl; + << '\n'; indent_down(); - indent(out) << "} catch (e: org.apache.thrift.transport.TTransportException) {" << endl; + indent(out) << "} catch (e: org.apache.thrift.transport.TTransportException) {" << '\n'; indent_up(); indent(out) << "logger.error(\"TTransportException writing to internal frame buffer\", e)" - << endl; - indent(out) << "fb.close()" << endl; + << '\n'; + indent(out) << "fb.close()" << '\n'; indent_down(); - indent(out) << "} catch (e: Exception) {" << endl; + indent(out) << "} catch (e: Exception) {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception writing to internal frame buffer\", e)" << endl; - indent(out) << "onError(e)" << endl; + indent(out) << "logger.error(\"Exception writing to internal frame buffer\", e)" << '\n'; + indent(out) << "onError(e)" << '\n'; scope_down(out); } scope_down(out); } { - indent(out) << "override fun onError(exception: kotlin.Exception) {" << endl; + indent(out) << "override fun onError(exception: kotlin.Exception) {" << '\n'; indent_up(); if (tfunc->is_oneway()) { indent(out) << "if (exception is org.apache.thrift.transport.TTransportException) {" - << endl; + << '\n'; indent_up(); - indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << endl; - indent(out) << "fb.close()" << endl; + indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n'; + indent(out) << "fb.close()" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception inside oneway handler\", exception)" << endl; + indent(out) << "logger.error(\"Exception inside oneway handler\", exception)" << '\n'; scope_down(out); } else { - indent(out) << "val (msgType, msg) = when (exception) {" << endl; + indent(out) << "val (msgType, msg) = when (exception) {" << '\n'; indent_up(); auto xceptions = tfunc->get_xceptions()->get_members(); for (auto xception : xceptions) { - indent(out) << "is " << type_name(xception->get_type()) << " -> {" << endl; + indent(out) << "is " << type_name(xception->get_type()) << " -> {" << '\n'; indent_up(); string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "()" << endl; - indent(out) << "result." << xception->get_name() << " = exception" << endl; - indent(out) << "org.apache.thrift.protocol.TMessageType.REPLY to result" << endl; + indent(out) << "val result = " << result_name << "()" << '\n'; + indent(out) << "result." << xception->get_name() << " = exception" << '\n'; + indent(out) << "org.apache.thrift.protocol.TMessageType.REPLY to result" << '\n'; scope_down(out); } - indent(out) << "is org.apache.thrift.transport.TTransportException -> {" << endl; + indent(out) << "is org.apache.thrift.transport.TTransportException -> {" << '\n'; indent_up(); - indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << endl; - indent(out) << "fb.close()" << endl; - indent(out) << "return" << endl; + indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n'; + indent(out) << "fb.close()" << '\n'; + indent(out) << "return" << '\n'; scope_down(out); - indent(out) << "is org.apache.thrift.TApplicationException -> {" << endl; + indent(out) << "is org.apache.thrift.TApplicationException -> {" << '\n'; indent_up(); indent(out) << "logger.error(\"TApplicationException inside handler\", exception)" - << endl; - indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to exception" << endl; + << '\n'; + indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to exception" << '\n'; scope_down(out); - indent(out) << "else -> {" << endl; + indent(out) << "else -> {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception inside handler\", exception)" << endl; + indent(out) << "logger.error(\"Exception inside handler\", exception)" << '\n'; indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.INTERNAL_ERROR, exception.message)" - << endl; + << '\n'; scope_down(out); scope_down(out); - indent(out) << "try {" << endl; + indent(out) << "try {" << '\n'; indent_up(); - indent(out) << "sendResponse(fb, msg, msgType, seqid)" << endl; + indent(out) << "sendResponse(fb, msg, msgType, seqid)" << '\n'; indent_down(); - indent(out) << "} catch (ex: java.lang.Exception) {" << endl; + indent(out) << "} catch (ex: java.lang.Exception) {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception writing to internal frame buffer\", ex)" << endl; - indent(out) << "fb.close()" << endl; + indent(out) << "logger.error(\"Exception writing to internal frame buffer\", ex)" << '\n'; + indent(out) << "fb.close()" << '\n'; scope_down(out); } @@ -1825,7 +1834,7 @@ void t_kotlin_generator::generate_service_result_helpers(t_service* tservice) { generate_docstring_comment(out, "/**\n", " * ", "function result for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "sealed interface " << tservice->get_name() << "FunctionResult {" << endl; + indent(out) << "sealed interface " << tservice->get_name() << "FunctionResult {" << '\n'; indent_up(); for (auto func : tservice->get_functions()) { if (func->is_oneway()) { @@ -1852,12 +1861,12 @@ void t_kotlin_generator::generate_service_args_helpers(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); generate_docstring_comment(out, "/**\n", " * ", "function arguments for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "sealed interface " << tservice->get_name() << "FunctionArgs {" << endl; + indent(out) << "sealed interface " << tservice->get_name() << "FunctionArgs {" << '\n'; indent_up(); for (auto func : tservice->get_functions()) { t_struct* ts = func->get_arglist(); generate_struct_definition(out, ts, false, tservice->get_name() + "FunctionArgs"); - out << endl; + out << '\n'; } scope_down(out); out.close(); @@ -1961,7 +1970,7 @@ bool t_kotlin_generator::is_enum_map(t_type* ttype) { */ string t_kotlin_generator::kotlin_package() { if (!package_name_.empty()) { - return string("package ") + package_name_ + endl + endl; + return string("package ") + package_name_ + "\n" + "\n"; } return ""; } @@ -1969,8 +1978,7 @@ string t_kotlin_generator::kotlin_package() { string t_kotlin_generator::warning_surpressions() { return "@file:Suppress(\"ClassName\", \"PropertyName\", \"RedundantUnitReturnType\", " "\"NestedLambdaShadowedImplicitParameter\", " - "\"RemoveRedundantQualifierName\")" - + endl; + "\"RemoveRedundantQualifierName\")\n"; } string t_kotlin_generator::constant_name(string name) { diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc index 0dc7743f479..f7f8f054e08 100644 --- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc @@ -26,8 +26,6 @@ using std::string; using std::vector; using std::map; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * LUA code generator. * @@ -190,7 +188,7 @@ void t_lua_generator::init_generator() { f_consts_ << autogen_comment() << lua_includes(); f_types_ << autogen_comment() << lua_includes(); if (gen_requires_) { - f_types_ << endl << "require '" << cur_namespace << "constants'"; + f_types_ << '\n' << "require '" << cur_namespace << "constants'"; } } @@ -207,7 +205,7 @@ void t_lua_generator::generate_typedef(t_typedef* ttypedef) { if (ttypedef->get_type()->get_name().empty()) { return; } - f_types_ << endl << endl << indent() << ttypedef->get_symbolic() << " = " + f_types_ << '\n' << '\n' << indent() << ttypedef->get_symbolic() << " = " << ttypedef->get_type()->get_name(); } @@ -215,7 +213,7 @@ void t_lua_generator::generate_typedef(t_typedef* ttypedef) { * Generates code for an enumerated type (table) */ void t_lua_generator::generate_enum(t_enum* tenum) { - f_types_ << endl << endl << tenum->get_name() << " = {" << endl; + f_types_ << '\n' << '\n' << tenum->get_name() << " = {" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -227,7 +225,7 @@ void t_lua_generator::generate_enum(t_enum* tenum) { if (c_iter != constants.end()) { f_types_ << ","; } - f_types_ << endl; + f_types_ << '\n'; } f_types_ << "}"; } @@ -240,7 +238,7 @@ void t_lua_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); t_const_value* value = tconst->get_value(); - f_consts_ << endl << endl << name << " = "; + f_consts_ << '\n' << '\n' << name << " = "; f_consts_ << render_const_value(type, value); } @@ -275,13 +273,16 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { out << value->get_double(); } break; + case t_base_type::TYPE_UUID: + out << "TUUIDfromString(" << value->get_string() << ")"; + break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << type->get_name() << " = {" << endl; + out << type->get_name() << " = {" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -312,7 +313,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { out << "}"; indent_down(); } else if (type->is_map()) { - out << type->get_name() << "{" << endl; + out << type->get_name() << "{" << '\n'; indent_up(); t_type* ktype = ((t_map*)type)->get_key_type(); @@ -327,7 +328,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { if (v_iter != val.end()) { out << ","; } - out << endl; + out << '\n'; } indent_down(); indent(out) << "}"; @@ -338,7 +339,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { } else { etype = ((t_set*)type)->get_elem_type(); } - out << type->get_name() << " = {" << endl; + out << type->get_name() << " = {" << '\n'; const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end();) { @@ -351,7 +352,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { } ++v_iter; if (v_iter != val.end()) { - out << "," << endl; + out << "," << '\n'; } } out << "}"; @@ -382,15 +383,15 @@ void t_lua_generator::generate_lua_struct_definition(ostream& out, vector::const_iterator m_iter; const vector& members = tstruct->get_members(); - indent(out) << endl << endl << tstruct->get_name(); + indent(out) << '\n' << '\n' << tstruct->get_name(); if (is_exception) { - out << " = TException:new{" << endl << indent() << " __type = '" << tstruct->get_name() << "'"; + out << " = TException:new{" << '\n' << indent() << " __type = '" << tstruct->get_name() << "'"; if (members.size() > 0) { out << ","; } - out << endl; + out << '\n'; } else { - out << " = __TObject:new{" << endl; + out << " = __TObject:new{" << '\n'; } indent_up(); for (m_iter = members.begin(); m_iter != members.end();) { @@ -398,12 +399,12 @@ void t_lua_generator::generate_lua_struct_definition(ostream& out, out << (*m_iter)->get_name(); ++m_iter; if (m_iter != members.end()) { - out << "," << endl; + out << "," << '\n'; } } indent_down(); indent(out); - out << endl << "}"; + out << '\n' << "}"; generate_lua_struct_reader(out, tstruct); generate_lua_struct_writer(out, tstruct); @@ -417,48 +418,48 @@ void t_lua_generator::generate_lua_struct_reader(ostream& out, t_struct* tstruct vector::const_iterator f_iter; // function - indent(out) << endl << endl << "function " << tstruct->get_name() << ":read(iprot)" << endl; + indent(out) << '\n' << '\n' << "function " << tstruct->get_name() << ":read(iprot)" << '\n'; indent_up(); - indent(out) << "iprot:readStructBegin()" << endl; + indent(out) << "iprot:readStructBegin()" << '\n'; // while: Read in fields - indent(out) << "while true do" << endl; + indent(out) << "while true do" << '\n'; indent_up(); // if: Check what to read - indent(out) << "local fname, ftype, fid = iprot:readFieldBegin()" << endl; - indent(out) << "if ftype == TType.STOP then" << endl; + indent(out) << "local fname, ftype, fid = iprot:readFieldBegin()" << '\n'; + indent(out) << "if ftype == TType.STOP then" << '\n'; indent_up(); - indent(out) << "break" << endl; + indent(out) << "break" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent_down(); - indent(out) << "elseif fid == " << (*f_iter)->get_key() << " then" << endl; + indent(out) << "elseif fid == " << (*f_iter)->get_key() << " then" << '\n'; indent_up(); - indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << " then" << endl; + indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << " then" << '\n'; indent_up(); // Read field contents generate_deserialize_field(out, *f_iter, false, "self."); indent_down(); - indent(out) << "else" << endl; - indent(out) << " iprot:skip(ftype)" << endl; - indent(out) << "end" << endl; + indent(out) << "else" << '\n'; + indent(out) << " iprot:skip(ftype)" << '\n'; + indent(out) << "end" << '\n'; } // end if indent_down(); - indent(out) << "else" << endl; - indent(out) << " iprot:skip(ftype)" << endl; - indent(out) << "end" << endl; - indent(out) << "iprot:readFieldEnd()" << endl; + indent(out) << "else" << '\n'; + indent(out) << " iprot:skip(ftype)" << '\n'; + indent(out) << "end" << '\n'; + indent(out) << "iprot:readFieldEnd()" << '\n'; // end while indent_down(); - indent(out) << "end" << endl; - indent(out) << "iprot:readStructEnd()" << endl; + indent(out) << "end" << '\n'; + indent(out) << "iprot:readStructEnd()" << '\n'; // end function indent_down(); @@ -474,28 +475,28 @@ void t_lua_generator::generate_lua_struct_writer(ostream& out, t_struct* tstruct vector::const_iterator f_iter; // function - indent(out) << endl << endl << "function " << tstruct->get_name() << ":write(oprot)" << endl; + indent(out) << '\n' << '\n' << "function " << tstruct->get_name() << ":write(oprot)" << '\n'; indent_up(); - indent(out) << "oprot:writeStructBegin('" << tstruct->get_name() << "')" << endl; + indent(out) << "oprot:writeStructBegin('" << tstruct->get_name() << "')" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { // To check element of self whether nil or not. // avoid the value(false) of BOOL is lost. - indent(out) << "if self." << (*f_iter)->get_name() << " ~= nil then" << endl; + indent(out) << "if self." << (*f_iter)->get_name() << " ~= nil then" << '\n'; indent_up(); indent(out) << "oprot:writeFieldBegin('" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) << ", " << (*f_iter)->get_key() << ")" - << endl; + << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self."); - indent(out) << "oprot:writeFieldEnd()" << endl; + indent(out) << "oprot:writeFieldEnd()" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } - indent(out) << "oprot:writeFieldStop()" << endl; - indent(out) << "oprot:writeStructEnd()" << endl; + indent(out) << "oprot:writeFieldStop()" << '\n'; + indent(out) << "oprot:writeStructEnd()" << '\n'; // end function indent_down(); @@ -518,15 +519,15 @@ void t_lua_generator::generate_service(t_service* tservice) { // Headers f_service_ << autogen_comment() << lua_includes(); if (gen_requires_) { - f_service_ << endl << "require '" << cur_ns << "ttypes'" << endl; + f_service_ << '\n' << "require '" << cur_ns << "ttypes'" << '\n'; if (tservice->get_extends() != nullptr) { f_service_ << "require '" << get_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "'" << endl; + << tservice->get_extends()->get_name() << "'" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_client(f_service_, tservice); generate_service_interface(f_service_, tservice); @@ -544,11 +545,11 @@ void t_lua_generator::generate_service_interface(ostream& out, t_service* tservi // Interface object definition out << classname << " = "; if (extends_s) { - out << extends_s->get_name() << "Iface:new{" << endl; + out << extends_s->get_name() << "Iface:new{" << '\n'; } else { - out << "__TObject:new{" << endl; + out << "__TObject:new{" << '\n'; } - out << " __type = '" << classname << "'" << endl << "}" << endl << endl; + out << " __type = '" << classname << "'" << '\n' << "}" << '\n' << '\n'; } void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) { @@ -562,7 +563,7 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) } else { out << "__TClient"; } - out << ", {" << endl << " __type = '" << classname << "'" << endl << "})" << endl; + out << ", {" << '\n' << " __type = '" << classname << "'" << '\n' << "})" << '\n'; // Send/Recv functions vector functions = tservice->get_functions(); @@ -572,28 +573,28 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) string funcname = (*f_iter)->get_name(); // Wrapper function - indent(out) << endl << "function " << classname << ":" << sig << endl; + indent(out) << '\n' << "function " << classname << ":" << sig << '\n'; indent_up(); - indent(out) << "self:send_" << sig << endl << indent(); + indent(out) << "self:send_" << sig << '\n' << indent(); if (!(*f_iter)->is_oneway()) { if (!(*f_iter)->get_returntype()->is_void()) { out << "return "; } - out << "self:recv_" << sig << endl; + out << "self:recv_" << sig << '\n'; } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Send function - indent(out) << endl << "function " << classname << ":send_" << sig << endl; + indent(out) << '\n' << "function " << classname << ":send_" << sig << '\n'; indent_up(); indent(out) << "self.oprot:writeMessageBegin('" << funcname << "', " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", self._seqid)" << endl; - indent(out) << "local args = " << funcname << "_args:new{}" << endl; + << ", self._seqid)" << '\n'; + indent(out) << "local args = " << funcname << "_args:new{}" << '\n'; // Set the args const vector& args = (*f_iter)->get_arglist()->get_members(); @@ -603,60 +604,60 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) if ((*fld_iter)->get_value() != nullptr) { // Insert default value for nil arguments t_type* type = get_true_type((*fld_iter)->get_type()); - indent(out) << "if " << argname << " ~= nil then" << endl; + indent(out) << "if " << argname << " ~= nil then" << '\n'; indent_up(); - indent(out) << "args." << argname << " = " << argname << endl; + indent(out) << "args." << argname << " = " << argname << '\n'; indent_down(); - indent(out) << "else" << endl; + indent(out) << "else" << '\n'; indent_up(); - indent(out) << "args." << argname << " = " << render_const_value(type, (*fld_iter)->get_value()) << endl; + indent(out) << "args." << argname << " = " << render_const_value(type, (*fld_iter)->get_value()) << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else { - indent(out) << "args." << argname << " = " << argname << endl; + indent(out) << "args." << argname << " = " << argname << '\n'; } } - indent(out) << "args:write(self.oprot)" << endl; - indent(out) << "self.oprot:writeMessageEnd()" << endl; - indent(out) << "self.oprot.trans:flush()" << endl; + indent(out) << "args:write(self.oprot)" << '\n'; + indent(out) << "self.oprot:writeMessageEnd()" << '\n'; + indent(out) << "self.oprot.trans:flush()" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Recv function if (!(*f_iter)->is_oneway()) { - indent(out) << endl << "function " << classname << ":recv_" << sig << endl; + indent(out) << '\n' << "function " << classname << ":recv_" << sig << '\n'; indent_up(); out << indent() << "local fname, mtype, rseqid = self.iprot:" - << "readMessageBegin()" << endl << indent() << "if mtype == TMessageType.EXCEPTION then" - << endl << indent() << " local x = TApplicationException:new{}" << endl << indent() - << " x:read(self.iprot)" << endl << indent() << " self.iprot:readMessageEnd()" << endl - << indent() << " error(x)" << endl << indent() << "end" << endl << indent() - << "local result = " << funcname << "_result:new{}" << endl << indent() - << "result:read(self.iprot)" << endl << indent() << "self.iprot:readMessageEnd()" << endl; + << "readMessageBegin()" << '\n' << indent() << "if mtype == TMessageType.EXCEPTION then" + << '\n' << indent() << " local x = TApplicationException:new{}" << '\n' << indent() + << " x:read(self.iprot)" << '\n' << indent() << " self.iprot:readMessageEnd()" << '\n' + << indent() << " error(x)" << '\n' << indent() << "end" << '\n' << indent() + << "local result = " << funcname << "_result:new{}" << '\n' << indent() + << "result:read(self.iprot)" << '\n' << indent() << "self.iprot:readMessageEnd()" << '\n'; // Return the result if it's not a void function if (!(*f_iter)->get_returntype()->is_void()) { - out << indent() << "if result.success ~= nil then" << endl << indent() << " return result.success" - << endl; + out << indent() << "if result.success ~= nil then" << '\n' << indent() << " return result.success" + << '\n'; // Throw custom exceptions const std::vector& xf = (*f_iter)->get_xceptions()->get_members(); vector::const_iterator x_iter; for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) { - out << indent() << "elseif result." << (*x_iter)->get_name() << " then" << endl - << indent() << " error(result." << (*x_iter)->get_name() << ")" << endl; + out << indent() << "elseif result." << (*x_iter)->get_name() << " then" << '\n' + << indent() << " error(result." << (*x_iter)->get_name() << ")" << '\n'; } - out << indent() << "end" << endl << indent() + out << indent() << "end" << '\n' << indent() << "error(TApplicationException:new{errorCode = " - << "TApplicationException.MISSING_RESULT})" << endl; + << "TApplicationException.MISSING_RESULT})" << '\n'; } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } } } @@ -666,40 +667,40 @@ void t_lua_generator::generate_service_processor(ostream& out, t_service* tservi t_service* extends_s = tservice->get_extends(); // Define processor table - out << endl << classname << " = __TObject.new("; + out << '\n' << classname << " = __TObject.new("; if (extends_s != nullptr) { - out << extends_s->get_name() << "Processor" << endl; + out << extends_s->get_name() << "Processor" << '\n'; } else { - out << "__TProcessor" << endl; + out << "__TProcessor" << '\n'; } - out << ", {" << endl << " __type = '" << classname << "'" << endl << "})" << endl; + out << ", {" << '\n' << " __type = '" << classname << "'" << '\n' << "})" << '\n'; // Process function - indent(out) << endl << "function " << classname << ":process(iprot, oprot, server_ctx)" << endl; + indent(out) << '\n' << "function " << classname << ":process(iprot, oprot, server_ctx)" << '\n'; indent_up(); - indent(out) << "local name, mtype, seqid = iprot:readMessageBegin()" << endl; - indent(out) << "local func_name = 'process_' .. name" << endl; - indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then" << endl; + indent(out) << "local name, mtype, seqid = iprot:readMessageBegin()" << '\n'; + indent(out) << "local func_name = 'process_' .. name" << '\n'; + indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then" << '\n'; indent_up(); indent(out) << "if oprot ~= nil then"; indent_up(); - out << endl << indent() << "iprot:skip(TType.STRUCT)" << endl << indent() - << "iprot:readMessageEnd()" << endl << indent() << "x = TApplicationException:new{" << endl - << indent() << " errorCode = TApplicationException.UNKNOWN_METHOD" << endl << indent() << "}" - << endl << indent() << "oprot:writeMessageBegin(name, TMessageType.EXCEPTION, " - << "seqid)" << endl << indent() << "x:write(oprot)" << endl << indent() - << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl; + out << '\n' << indent() << "iprot:skip(TType.STRUCT)" << '\n' << indent() + << "iprot:readMessageEnd()" << '\n' << indent() << "x = TApplicationException:new{" << '\n' + << indent() << " errorCode = TApplicationException.UNKNOWN_METHOD" << '\n' << indent() << "}" + << '\n' << indent() << "oprot:writeMessageBegin(name, TMessageType.EXCEPTION, " + << "seqid)" << '\n' << indent() << "x:write(oprot)" << '\n' << indent() + << "oprot:writeMessageEnd()" << '\n' << indent() << "oprot.trans:flush()" << '\n'; indent_down(); - out << indent() << "end" << endl << indent() - << "return false, 'Unknown function '..name" << endl; + out << indent() << "end" << '\n' << indent() + << "return false, 'Unknown function '..name" << '\n'; indent_down(); - indent(out) << "else" << endl << indent() - << " return self[func_name](self, seqid, iprot, oprot, server_ctx)" << endl << indent() - << "end" << endl; + indent(out) << "else" << '\n' << indent() + << " return self[func_name](self, seqid, iprot, oprot, server_ctx)" << '\n' << indent() + << "end" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Generate the process subfunctions vector functions = tservice->get_functions(); @@ -717,18 +718,20 @@ void t_lua_generator::generate_process_function(ostream& out, string resultname = tfunction->get_name() + "_result"; string fn_name = tfunction->get_name(); - indent(out) << endl << "function " << classname << ":process_" << fn_name - << "(seqid, iprot, oprot, server_ctx)" << endl; + indent(out) << '\n' << "function " << classname << ":process_" << fn_name + << "(seqid, iprot, oprot, server_ctx)" << '\n'; indent_up(); // Read the request - out << indent() << "local args = " << argsname << ":new{}" << endl << indent() - << "local reply_type = TMessageType.REPLY" << endl << indent() << "args:read(iprot)" << endl - << indent() << "iprot:readMessageEnd()" << endl; + out << indent() << "local args = " << argsname << ":new{}" << '\n' << indent() + << "local reply_type = TMessageType.REPLY" << '\n' << indent() << "args:read(iprot)" << '\n' + << indent() << "iprot:readMessageEnd()" << '\n'; if (!tfunction->is_oneway()) { out << indent() << "local result = " << resultname - << ":new{}" << endl; + << ":new{}" << '\n'; + } else { + out << indent() << "oprot.trans:flushOneway()" << '\n'; } out << indent() << "local status, res = pcall(self.handler." << fn_name @@ -738,13 +741,13 @@ void t_lua_generator::generate_process_function(ostream& out, if (args->get_members().size() > 0) { out << ", " << argument_list(args, "args."); } - out << ")" << endl; + out << ")" << '\n'; if (!tfunction->is_oneway()) { // Check for errors - out << indent() << "if not status then" << endl << indent() - << " reply_type = TMessageType.EXCEPTION" << endl << indent() - << " result = TApplicationException:new{message = res}" << endl; + out << indent() << "if not status then" << '\n' << indent() + << " reply_type = TMessageType.EXCEPTION" << '\n' << indent() + << " result = TApplicationException:new{message = res}" << '\n'; // Handle custom exceptions const std::vector& xf = tfunction->get_xceptions()->get_members(); @@ -752,19 +755,19 @@ void t_lua_generator::generate_process_function(ostream& out, vector::const_iterator x_iter; for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) { out << indent() << "elseif ttype(res) == '" << (*x_iter)->get_type()->get_name() << "' then" - << endl << indent() << " result." << (*x_iter)->get_name() << " = res" << endl; + << '\n' << indent() << " result." << (*x_iter)->get_name() << " = res" << '\n'; } } // Set the result and write the reply - out << indent() << "else" << endl << indent() << " result.success = res" << endl << indent() - << "end" << endl << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, " - << "seqid)" << endl << indent() << "result:write(oprot)" << endl << indent() - << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl; + out << indent() << "else" << '\n' << indent() << " result.success = res" << '\n' << indent() + << "end" << '\n' << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, " + << "seqid)" << '\n' << indent() << "result:write(oprot)" << '\n' << indent() + << "oprot:writeMessageEnd()" << '\n' << indent() << "oprot.trans:flush()" << '\n'; } - out << indent() << "return status, res" << endl; + out << indent() << "return status, res" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } // Service helpers @@ -772,7 +775,7 @@ void t_lua_generator::generate_service_helpers(ostream& out, t_service* tservice vector functions = tservice->get_functions(); vector::iterator f_iter; - out << endl << "-- HELPER FUNCTIONS AND STRUCTURES"; + out << '\n' << "-- HELPER FUNCTIONS AND STRUCTURES"; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); generate_lua_struct_definition(out, ts, false); @@ -847,13 +850,16 @@ void t_lua_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_DOUBLE: out << "readDouble()"; break; + case t_base_type::TYPE_UUID: + out << "readUuid()"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << "readI32()"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -867,7 +873,7 @@ void t_lua_generator::generate_deserialize_struct(ostream& out, bool local, string prefix) { indent(out) << (local ? "local " : "") << prefix << " = " << tstruct->get_name() << ":new{}" - << endl << indent() << prefix << ":read(iprot)" << endl; + << '\n' << indent() << prefix << ":read(iprot)" << '\n'; } void t_lua_generator::generate_deserialize_container(ostream& out, @@ -885,18 +891,18 @@ void t_lua_generator::generate_deserialize_container(ostream& out, t_field fetype(g_type_i8, etype); // Declare variables, read header - indent(out) << (local ? "local " : "") << prefix << " = {}" << endl; + indent(out) << (local ? "local " : "") << prefix << " = {}" << '\n'; if (ttype->is_map()) { indent(out) << "local " << ktype << ", " << vtype << ", " << size << " = iprot:readMapBegin() " - << endl; + << '\n'; } else if (ttype->is_set()) { - indent(out) << "local " << etype << ", " << size << " = iprot:readSetBegin()" << endl; + indent(out) << "local " << etype << ", " << size << " = iprot:readSetBegin()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "local " << etype << ", " << size << " = iprot:readListBegin()" << endl; + indent(out) << "local " << etype << ", " << size << " = iprot:readListBegin()" << '\n'; } // Deserialize - indent(out) << "for _i=1," << size << " do" << endl; + indent(out) << "for _i=1," << size << " do" << '\n'; indent_up(); if (ttype->is_map()) { @@ -908,15 +914,15 @@ void t_lua_generator::generate_deserialize_container(ostream& out, } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Read container end if (ttype->is_map()) { - indent(out) << "iprot:readMapEnd()" << endl; + indent(out) << "iprot:readMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot:readSetEnd()" << endl; + indent(out) << "iprot:readSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot:readListEnd()" << endl; + indent(out) << "iprot:readListEnd()" << '\n'; } } @@ -930,7 +936,7 @@ void t_lua_generator::generate_deserialize_map_element(ostream& out, t_map* tmap generate_deserialize_field(out, &fkey, true); generate_deserialize_field(out, &fval, true); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { @@ -940,7 +946,7 @@ void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset generate_deserialize_field(out, &felem, true); - indent(out) << prefix << "[" << elem << "] = " << elem << endl; + indent(out) << prefix << "[" << elem << "] = " << elem << '\n'; } void t_lua_generator::generate_deserialize_list_element(ostream& out, @@ -953,7 +959,7 @@ void t_lua_generator::generate_deserialize_list_element(ostream& out, generate_deserialize_field(out, &felem, true); - indent(out) << "table.insert(" << prefix << ", " << elem << ")" << endl; + indent(out) << "table.insert(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -1002,13 +1008,16 @@ void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, st case t_base_type::TYPE_DOUBLE: out << "writeDouble(" << name << ")"; break; + case t_base_type::TYPE_UUID: + out << "writeUuid(" << name << ")"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << "writeI32(" << name << ")"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n", name.c_str(), @@ -1018,7 +1027,7 @@ void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, st void t_lua_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ":write(oprot)" << endl; + indent(out) << prefix << ":write(oprot)" << '\n'; } void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) { @@ -1026,48 +1035,48 @@ void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { indent(out) << "oprot:writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "ttable_size(" << prefix << "))" << endl; + << "ttable_size(" << prefix << "))" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot:writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "ttable_size(" << prefix << "))" << endl; + << "ttable_size(" << prefix << "))" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot:writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "#" << prefix << ")" << endl; + << "#" << prefix << ")" << '\n'; } // Serialize if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - indent(out) << "for " << kiter << "," << viter << " in pairs(" << prefix << ") do" << endl; + indent(out) << "for " << kiter << "," << viter << " in pairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for " << iter << ",_ in pairs(" << prefix << ") do" << endl; + indent(out) << "for " << iter << ",_ in pairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for _," << iter << " in ipairs(" << prefix << ") do" << endl; + indent(out) << "for _," << iter << " in ipairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } // Finish writing if (ttype->is_map()) { - indent(out) << "oprot:writeMapEnd()" << endl; + indent(out) << "oprot:writeMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot:writeSetEnd()" << endl; + indent(out) << "oprot:writeSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot:writeListEnd()" << endl; + indent(out) << "oprot:writeListEnd()" << '\n'; } } @@ -1153,6 +1162,8 @@ string t_lua_generator::type_to_enum(t_type* type) { return "TType.I64"; case t_base_type::TYPE_DOUBLE: return "TType.DOUBLE"; + case t_base_type::TYPE_UUID: + return "TType.UUID"; default: throw "compiler error: unhandled type"; } diff --git a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc index 76fe98b4e53..fbcaccca02e 100644 --- a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc @@ -38,9 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const char endl = '\n'; // avoid ostream << std::endl flushes - - /** * MARKDOWN code generator * @@ -55,7 +52,7 @@ enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; const std::map& parsed_options, const std::string& option_string) : t_generator(program) { - + (void)option_string; std::map::const_iterator iter; @@ -128,14 +125,14 @@ enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; /** - * string to markdown-id link reference + * string to markdown-id link reference */ std::string t_markdown_generator::str_to_id(const std::string& s) { std::string id; for(auto chr=s.begin();chr<=s.end(); ++chr) { if(*chr == '.' || *chr == 0) continue; - id += tolower(*chr); + id += tolower(*chr); } return id; } @@ -144,10 +141,10 @@ std::string t_markdown_generator::str_to_id(const std::string& s) { * Emits the Table of Contents links at the top of the module's page */ void t_markdown_generator::generate_program_toc() { - f_out_ << "| Module | Services & Functions | Data types | Constants |" << endl - << "| --- | --- | --- | --- |" << endl; + f_out_ << "| Module | Services & Functions | Data types | Constants |" << '\n' + << "| --- | --- | --- | --- |" << '\n'; generate_program_toc_row(program_); - f_out_ << endl; + f_out_ << '\n'; } /** @@ -191,24 +188,24 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { fill = &filling.back(); } string name = get_service_name(*sv_iter); - (*fill)[1] = "[" + name + "](" - + make_file_link(fname) + (*fill)[1] = "[" + name + "](" + + make_file_link(fname) + "#service-" + str_to_id(name) + ")"; - + vector functions = (*sv_iter)->get_functions(); vector::iterator fn_iter; - for (fn_iter = functions.begin(); fn_iter != functions.end(); ++fn_iter) { - string fn_name = (*fn_iter)->get_name(); + for (fn_iter = functions.begin(); fn_iter != functions.end(); ++fn_iter) { + string fn_name = (*fn_iter)->get_name(); filling.emplace_back(); fill = &filling.back(); - (*fill)[1] = " [ • " + fn_name + "](" - + make_file_link(fname) + (*fill)[1] = " [ • " + fn_name + "](" + + make_file_link(fname) + "#function-" + str_to_id(name + fn_name) + ")"; } } } - - // Data Types Column + + // Data Types Column auto it_fill = filling.begin(); if (!tprog->get_enums().empty()) { @@ -224,8 +221,8 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*en_iter)->get_name(); - (*fill)[2] = "[" + name + "](" - + make_file_link(fname) + (*fill)[2] = "[" + name + "](" + + make_file_link(fname) + "#enumeration-" + str_to_id(name) + ")"; } } @@ -242,15 +239,15 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*td_iter)->get_symbolic(); - (*fill)[2] = "[" + name + "](" - + make_file_link(fname) + (*fill)[2] = "[" + name + "](" + + make_file_link(fname) + "#typedef-" + str_to_id(name) + ")"; } } if (!tprog->get_objects().empty()) { vector objects = tprog->get_objects(); vector::iterator o_iter; - for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { + for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { if(it_fill == filling.end()) { filling.emplace_back(); fill = &filling.back(); @@ -261,7 +258,7 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { } string name = (*o_iter)->get_name(); (*fill)[2] = "[" + name + "](" + make_file_link(fname); - + if ((*o_iter)->is_xception()) { (*fill)[2] += "#exception-"; } else if ((*o_iter)->is_struct() && (*o_iter)->is_union()) { @@ -270,11 +267,11 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { (*fill)[2] += "#struct-"; } (*fill)[2] += str_to_id(name) + ")"; - + } } - - // Constants Column + + // Constants Column it_fill = filling.begin(); if (!tprog->get_consts().empty()) { @@ -291,19 +288,19 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*con_iter)->get_name(); - (*fill)[3] = "[" + name + "](" - + make_file_link(fname) + (*fill)[3] = "[" + name + "](" + + make_file_link(fname) + "#constant-" + str_to_id(name) + ")"; } - + } - + for(auto& fill : filling) { for(auto& c : fill) - f_out_ << '|' << c; - f_out_ << '|' << endl; + f_out_ << '|' << c; + f_out_ << '|' << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -318,24 +315,24 @@ void t_markdown_generator::generate_program() { current_file_ = make_file_name(pname); string fname = get_out_dir() + current_file_; f_out_.open(fname.c_str()); - f_out_ << "# Thrift module: " << pname << endl << endl; + f_out_ << "# Thrift module: " << pname << '\n' << '\n'; print_doc(program_); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; generate_program_toc(); if (!program_->get_consts().empty()) { - f_out_ << "***" << endl << "## Constants" << endl << endl; + f_out_ << "***" << '\n' << "## Constants" << '\n' << '\n'; vector consts = program_->get_consts(); - f_out_ << "|Constant|Type|Value||" << endl - << "|---|---|---|---|" << endl; + f_out_ << "|Constant|Type|Value||" << '\n' + << "|---|---|---|---|" << '\n'; generate_consts(consts); - f_out_ << endl; + f_out_ << '\n'; } if (!program_->get_enums().empty()) { - f_out_ << "***" << endl << "## Enumerations" << endl << endl; + f_out_ << "***" << '\n' << "## Enumerations" << '\n' << '\n'; // Generate enums vector enums = program_->get_enums(); vector::iterator en_iter; @@ -345,7 +342,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_typedefs().empty()) { - f_out_ << "***" << endl << "## Type declarations" << endl << endl; + f_out_ << "***" << '\n' << "## Type declarations" << '\n' << '\n'; // Generate typedefs vector typedefs = program_->get_typedefs(); vector::iterator td_iter; @@ -355,7 +352,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_objects().empty()) { - f_out_ << "***" << endl << "## Data structures" << endl << endl; + f_out_ << "***" << '\n' << "## Data structures" << '\n' << '\n'; // Generate structs and exceptions in declared order vector objects = program_->get_objects(); vector::iterator o_iter; @@ -369,7 +366,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_services().empty()) { - f_out_ << "***" << endl << "## Services" << endl << endl; + f_out_ << "***" << '\n' << "## Services" << '\n' << '\n'; // Generate services vector services = program_->get_services(); vector::iterator sv_iter; @@ -379,7 +376,7 @@ void t_markdown_generator::generate_program() { } } - f_out_ << endl; + f_out_ << '\n'; f_out_.close(); generate_index(); @@ -392,15 +389,15 @@ void t_markdown_generator::generate_index() { current_file_ = make_file_name("index"); string index_fname = get_out_dir() + current_file_; f_out_.open(index_fname.c_str()); - - f_out_ << "# Thrift declarations" << endl; - f_out_ << "| Module | Services & Functions | Data types | Constants |" - << endl - << "| --- | --- | --- | --- |" - << endl; + + f_out_ << "# Thrift declarations" << '\n'; + f_out_ << "| Module | Services & Functions | Data types | Constants |" + << '\n' + << "| --- | --- | --- | --- |" + << '\n'; vector programs; generate_program_toc_rows(program_, programs); - f_out_ << endl; + f_out_ << '\n'; f_out_.close(); } @@ -716,13 +713,13 @@ int t_markdown_generator::print_type(t_type* ttype) { f_out_ << ">"; } } else if (ttype->is_base_type()) { - f_out_ << "```" << (ttype->is_binary() ? "binary" : ttype->get_name()) + f_out_ << "```" << (ttype->is_binary() ? "binary" : ttype->get_name()) << "```"; len = ttype->get_name().size(); } else { string prog_name = ttype->get_program()->get_name(); string type_name = ttype->get_name(); - f_out_ << "[```" << type_name << "```](" + f_out_ << "[```" << type_name << "```](" << make_file_link(make_file_name(prog_name)) << "#"; if (ttype->is_typedef()) { f_out_ << "typedef-"; @@ -740,7 +737,7 @@ int t_markdown_generator::print_type(t_type* ttype) { } len = type_name.size(); if (ttype->get_program() != program_) { - f_out_ << str_to_id(prog_name); + f_out_ << str_to_id(prog_name); len += prog_name.size() + 1; } f_out_ << str_to_id(type_name) << ')'; @@ -757,8 +754,8 @@ void t_markdown_generator::print_const_value(t_type* type, t_const_value* tvalue if (tvalue->get_type() == t_const_value::CV_IDENTIFIER) { string fname = make_file_name(program_->get_name()); string name = escape_html(tvalue->get_identifier()); - f_out_ << "[```" << name << "```](" - + make_file_link(fname) + f_out_ << "[```" << name << "```](" + + make_file_link(fname) + "#constant-" + str_to_id(name) + ")"; return; } @@ -773,7 +770,7 @@ void t_markdown_generator::print_const_value(t_type* type, t_const_value* tvalue t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); f_out_ << "```"; switch (tbase) { - case t_base_type::TYPE_STRING: + case t_base_type::TYPE_STRING: f_out_ << escape_html(get_escaped_string(tvalue)); break; case t_base_type::TYPE_BOOL: @@ -893,17 +890,17 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { } if (has_docs) { arg_iter = args.begin(); - f_out_ << endl << "* parameters:" << endl; + f_out_ << '\n' << "* parameters:" << '\n'; for (int n = 1; arg_iter != args.end(); ++arg_iter, ++n ) { f_out_ << n << ". " << (*arg_iter)->get_name(); f_out_ << " - " << escape_html((*arg_iter)->get_doc()); - f_out_ << endl; + f_out_ << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } } - if(!has_docs) - f_out_ << endl; + if(!has_docs) + f_out_ << '\n'; has_docs = false; vector excepts = tfunction->get_xceptions()->get_members(); @@ -917,14 +914,14 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { } if (has_docs) { ex_iter = excepts.begin(); - f_out_ << "* exceptions:" << endl; + f_out_ << "* exceptions:" << '\n'; for (; ex_iter != excepts.end(); ex_iter++) { f_out_ << " * " << (*ex_iter)->get_type()->get_name(); f_out_ << " - "; f_out_ << escape_html((*ex_iter)->get_doc()); - f_out_ << endl; + f_out_ << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } } } @@ -936,13 +933,13 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { */ void t_markdown_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); - f_out_ << "### Typedef: " << name << endl; + f_out_ << "### Typedef: " << name << '\n'; print_doc(ttypedef); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; f_out_ << "_Base type_: **"; print_type(ttypedef->get_type()); - f_out_ << "**" << endl << endl; - f_out_ << endl; + f_out_ << "**" << '\n' << '\n'; + f_out_ << '\n'; } /** @@ -952,10 +949,10 @@ void t_markdown_generator::generate_typedef(t_typedef* ttypedef) { */ void t_markdown_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); - f_out_ << "### Enumeration: " << name << endl; + f_out_ << "### Enumeration: " << name << '\n'; print_doc(tenum); - f_out_ << endl << endl << "|Name|Value|Description|" << endl - << "|---|---|---|" << endl; + f_out_ << '\n' << '\n' << "|Name|Value|Description|" << '\n' + << "|---|---|---|" << '\n'; vector values = tenum->get_constants(); vector::iterator val_iter; for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) { @@ -965,9 +962,9 @@ void t_markdown_generator::generate_enum(t_enum* tenum) { f_out_ << (*val_iter)->get_value(); f_out_ << "```|"; print_doc((*val_iter)); - f_out_ << "|" << endl; + f_out_ << "|" << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -984,7 +981,7 @@ void t_markdown_generator::generate_const(t_const* tconst) { if (tconst->has_doc()) { print_doc(tconst); } - f_out_ << '|' << endl; + f_out_ << '|' << '\n'; } /** @@ -1002,14 +999,14 @@ void t_markdown_generator::generate_struct(t_struct* tstruct) { } else { f_out_ << "Struct: "; } - f_out_ << name << endl; + f_out_ << name << '\n'; print_doc(tstruct); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; vector members = tstruct->get_members(); vector::iterator mem_iter = members.begin(); f_out_ << "| Key | Field | Type | Description | Requiredness " - "| Default value |" << endl - << "| --- | --- | --- | --- | --- | --- |" << endl; + "| Default value |" << '\n' + << "| --- | --- | --- | --- | --- | --- |" << '\n'; for (; mem_iter != members.end(); mem_iter++) { f_out_ << '|' << (*mem_iter)->get_key(); f_out_ << '|' << (*mem_iter)->get_name(); @@ -1030,9 +1027,9 @@ void t_markdown_generator::generate_struct(t_struct* tstruct) { print_const_value((*mem_iter)->get_type(), default_val); f_out_ << "```"; } - f_out_ << '|' << endl; + f_out_ << '|' << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -1050,32 +1047,32 @@ void t_markdown_generator::generate_xception(t_struct* txception) { * @param tservice The service definition */ void t_markdown_generator::generate_service(t_service* tservice) { - f_out_ << "### Service: " << service_name_ << endl; + f_out_ << "### Service: " << service_name_ << '\n'; if (tservice->get_extends()) { f_out_ << "**extends ** _"; print_type(tservice->get_extends()); - f_out_ << "_" << endl; + f_out_ << "_" << '\n'; } print_doc(tservice); - f_out_ << endl; + f_out_ << '\n'; vector functions = tservice->get_functions(); vector::iterator fn_iter = functions.begin(); for (; fn_iter != functions.end(); fn_iter++) { string fn_name = (*fn_iter)->get_name(); - f_out_ << "#### Function: " << service_name_ << "." << fn_name << endl; + f_out_ << "#### Function: " << service_name_ << "." << fn_name << '\n'; print_doc(*fn_iter); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; print_type((*fn_iter)->get_returntype()); bool first = true; - f_out_ << endl << " _" << fn_name << "_("; + f_out_ << '\n' << " _" << fn_name << "_("; vector args = (*fn_iter)->get_arglist()->get_members(); vector::iterator arg_iter = args.begin(); for (; arg_iter != args.end(); arg_iter++) { if (!first) { - f_out_ << "," << endl; + f_out_ << "," << '\n'; } first = false; print_type((*arg_iter)->get_type()); @@ -1085,7 +1082,7 @@ void t_markdown_generator::generate_service(t_service* tservice) { print_const_value((*arg_iter)->get_type(), (*arg_iter)->get_value()); } } - f_out_ << ")" << endl; + f_out_ << ")" << '\n'; first = true; vector excepts = (*fn_iter)->get_xceptions()->get_members(); vector::iterator ex_iter = excepts.begin(); @@ -1098,10 +1095,10 @@ void t_markdown_generator::generate_service(t_service* tservice) { first = false; print_type((*ex_iter)->get_type()); } - f_out_ << endl; + f_out_ << '\n'; } print_fn_args_doc(*fn_iter); - f_out_ << endl; + f_out_ << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc index 1a27c0c3b2f..5c67f66dd14 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc @@ -82,8 +82,11 @@ t_netstd_generator::t_netstd_generator(t_program* program, const mapfirst.compare("no_deepcopy") == 0) { suppress_deepcopy = true; } - else if (iter->first.compare("net6") == 0) { - target_net_version = 6; + else if (iter->first.compare("net10") == 0) { + target_net_version = 10; + } + else if (iter->first.compare("net9") == 0) { + target_net_version = 9; } else if (iter->first.compare("net8") == 0) { target_net_version = 8; @@ -202,27 +205,136 @@ void t_netstd_generator::reset_indent() { void t_netstd_generator::pragmas_and_directives(ostream& out) { + if( target_net_version >= 10) { + out << "// targeting net 10" << '\n'; + out << "#if( !NET10_0_OR_GREATER)" << '\n'; + } else if( target_net_version >= 9) { + out << "// targeting net 9" << '\n'; + out << "#if( NET10_0_OR_GREATER || !NET9_0_OR_GREATER)" << '\n'; + } else if( target_net_version >= 8) { + out << "// targeting net 8" << '\n'; + out << "#if( NET9_0_OR_GREATER || !NET8_0_OR_GREATER)" << '\n'; + } else { + out << "// targeting netstandard 2.x" << '\n'; + out << "#if(! NETSTANDARD2_0_OR_GREATER)" << '\n'; + } + out << "#error Unexpected target platform. See 'thrift --help' for details." << '\n'; + out << "#endif" << '\n'; + out << '\n'; + if( target_net_version >= 6) { - out << "// Thrift code generated for net" << target_net_version << endl; - out << "#nullable enable // requires C# 8.0" << endl; + out << "// Thrift code generated for net" << target_net_version << '\n'; + out << "#nullable enable // requires C# 8.0" << '\n'; } // this one must be first - out << "#pragma warning disable IDE0079 // remove unnecessary pragmas" << endl; + out << "#pragma warning disable IDE0079 // remove unnecessary pragmas" << '\n'; - if( target_net_version >= 8) { - out << "#pragma warning disable IDE0290 // use primary CTOR" << endl; - } else { - out << "#pragma warning disable IDE0017 // object init can be simplified" << endl; - out << "#pragma warning disable IDE0028 // collection init can be simplified" << endl; + if( target_net_version >= 9) { + out << "#pragma warning disable IDE0130 // unexpected folder structure" << '\n'; + } + + if( target_net_version < 8) { + out << "#pragma warning disable IDE0017 // object init can be simplified" << '\n'; + out << "#pragma warning disable IDE0028 // collection init can be simplified" << '\n'; + out << "#pragma warning disable IDE0305 // collection init can be simplified" << '\n'; + out << "#pragma warning disable IDE0034 // simplify default expression" << '\n'; + out << "#pragma warning disable IDE0066 // use switch expression" << '\n'; + out << "#pragma warning disable IDE0090 // simplify new expression" << '\n'; + } + + out << "#pragma warning disable IDE0290 // use primary CTOR" << '\n'; + out << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << '\n'; + out << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << '\n'; + + if( any_deprecations()) { + out << "#pragma warning disable CS0618 // silence our own deprecation warnings" << '\n'; } - out << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << endl; - out << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << endl; if( target_net_version < 6) { - out << "#pragma warning disable IDE0083 // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << endl; + out << "#pragma warning disable IDE0083 // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << '\n'; } - out << endl; + out << '\n'; +} + + +bool t_netstd_generator::any_deprecations() +{ + // enums + vector enums = program_->get_enums(); + vector::iterator en_iter; + for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) { + if( is_deprecated((*en_iter)->annotations_)) { + return true; + } + + // enum values + vector evals = (*en_iter)->get_constants(); + vector::iterator ev_iter; + for (ev_iter = evals.begin(); ev_iter != evals.end(); ++ev_iter) { + if( is_deprecated((*ev_iter)->annotations_)) { + return true; + } + } + } + + // typedefs + vector typedefs = program_->get_typedefs(); + vector::iterator td_iter; + for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) { + if( is_deprecated((*td_iter)->annotations_)) { + return true; + } + } + + // structs, exceptions, unions + vector objects = program_->get_objects(); + vector::iterator o_iter; + for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { + if( is_deprecated((*o_iter)->annotations_)) { + return true; + } + + // struct members + const vector& members = (*o_iter)->get_members(); + vector::const_iterator m_iter; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if( is_deprecated((*m_iter)->annotations_)) { + return true; + } + } + } + + /* not yet + // constants + vector consts = program_->get_consts(); + vector::iterator c_iter; + for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { + if( is_deprecated((*c_iter)->annotations_)) { + return true; + } + } + */ + + // services + vector services = program_->get_services(); + vector::iterator sv_iter; + for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { + if( is_deprecated((*sv_iter)->annotations_)) { + return true; + } + + // service methods + vector functions = (*sv_iter)->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + if( is_deprecated((*f_iter)->annotations_)) { + return true; + } + } + } + + return false; } @@ -230,7 +342,20 @@ void t_netstd_generator::start_netstd_namespace(ostream& out) { if (!namespace_name_.empty()) { - out << "namespace " << namespace_name_ << endl; + std::string normalized; + + const char* delim = "."; + char* str = strdup(namespace_name_.c_str()); + char* next = strtok(str, delim); + while( next != NULL) { + if( normalized.length() > 0) { + normalized += "."; + } + normalized += normalize_name(next,false); + next = strtok(NULL, delim); + } + + out << "namespace " << normalized << '\n'; scope_up(out); } } @@ -261,6 +386,9 @@ string t_netstd_generator::netstd_type_usings() const if (is_wcf_enabled()) { namespaces += "using System.ServiceModel;\n"; + } + if (is_wcf_enabled() || is_serialize_enabled()) + { namespaces += "using System.Runtime.Serialization;\n"; } @@ -309,13 +437,15 @@ void t_netstd_generator::generate_enum(t_enum* tenum) void t_netstd_generator::generate_enum(ostream& out, t_enum* tenum) { reset_indent(); - out << autogen_comment() << endl; + out << autogen_comment(); + out << "using System;" << '\n' << '\n'; // needed for Obsolete() attribute pragmas_and_directives(out); start_netstd_namespace(out); generate_netstd_doc(out, tenum); - out << indent() << "public enum " << type_name(tenum,false) << endl; + generate_deprecation_attribute(out, tenum->annotations_); + out << indent() << "public enum " << type_name(tenum,false) << '\n'; scope_up(out); vector constants = tenum->get_constants(); @@ -325,7 +455,8 @@ void t_netstd_generator::generate_enum(ostream& out, t_enum* tenum) { generate_netstd_doc(out, *c_iter); int value = (*c_iter)->get_value(); - out << indent() << normalize_name((*c_iter)->get_name()) << " = " << value << "," << endl; + generate_deprecation_attribute(out, (*c_iter)->annotations_); + out << indent() << normalize_name((*c_iter)->get_name()) << " = " << value << "," << '\n'; } scope_down(out); @@ -356,12 +487,12 @@ void t_netstd_generator::generate_consts(ostream& out, vector consts) } reset_indent(); - out << autogen_comment() << netstd_type_usings() << endl << endl; + out << autogen_comment() << netstd_type_usings() << '\n' << '\n'; pragmas_and_directives(out); start_netstd_namespace(out); - out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << endl; + out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << '\n'; scope_up(out); @@ -416,7 +547,7 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type t_type* field_type = field->get_type(); string val = render_const_value(out, name, field_type, v_iter->second); - out << indent() << name << "." << prop_name(field) << " = " << val << ";" << endl; + out << indent() << name << "." << prop_name(field) << " = " << val << ";" << '\n'; } cleanup_member_name_mapping(static_cast(type)); @@ -431,7 +562,7 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type { string key = render_const_value(out, name, ktype, v_iter->first); string val = render_const_value(out, name, vtype, v_iter->second); - out << indent() << name << "[" << key << "]" << " = " << val << ";" << endl; + out << indent() << name << "[" << key << "]" << " = " << val << ";" << '\n'; } } else if (type->is_list() || type->is_set()) @@ -451,14 +582,14 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, name, etype, *v_iter); - out << indent() << name << ".Add(" << val << ");" << endl; + out << indent() << name << ".Add(" << val << ");" << '\n'; } } } void t_netstd_generator::print_const_constructor(ostream& out, vector consts) { - out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl; + out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << '\n'; scope_up(out); vector::iterator c_iter; @@ -494,30 +625,30 @@ bool t_netstd_generator::print_const_value(ostream& out, string name, t_type* ty if (type->is_base_type()) { string v2 = render_const_value(out, name, type, value); - out << name << " = " << v2 << ";" << endl; + out << name << " = " << v2 << ";" << '\n'; need_static_construction = false; } else if (type->is_enum()) { - out << name << " = " << type_name(type) << "." << value->get_identifier_name() << ";" << endl; + out << name << " = " << type_name(type) << "." << value->get_identifier_name() << ";" << '\n'; need_static_construction = false; } else if (type->is_struct() || type->is_xception()) { if(target_net_version >= 6) { - out << name << " = new();" << endl; + out << name << " = new();" << '\n'; } else { - out << name << " = new " << type_name(type) << "();" << endl; + out << name << " = new " << type_name(type) << "();" << '\n'; } } else if (type->is_map() || type->is_list() || type->is_set()) { if(target_net_version >= 8) { - out << name << " = [];" << endl; + out << name << " = [];" << '\n'; } else if(target_net_version >= 6) { - out << name << " = new();" << endl; + out << name << " = new();" << '\n'; } else { - out << name << " = new " << type_name(type) << "();" << endl; + out << name << " = new " << type_name(type) << "();" << '\n'; } } @@ -672,49 +803,53 @@ void t_netstd_generator::generate_extensions(ostream& out, map reset_indent(); out << autogen_comment() << netstd_type_usings() - << "using Thrift.Protocol;" << endl - << endl << endl; + << "using Thrift.Protocol;" << '\n' + << '\n' << '\n'; pragmas_and_directives(out); start_netstd_namespace(out); - out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Extensions" << endl; + out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Extensions" << '\n'; scope_up(out); bool needs_typecast = false; std::map::const_iterator iter; for( iter = types.begin(); iter != types.end(); ++iter) { - out << indent() << "public static bool Equals(this " << iter->first << " instance, object that)" << endl; + out << indent() << "public static bool Equals(this " << iter->first << " instance, object that)" << '\n'; scope_up(out); if( target_net_version >= 6) { - out << indent() << "if (that is not " << iter->first << " other) return false;" << endl; + out << indent() << "if (that is not " << iter->first << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << iter->first << " other)) return false;" << endl; + out << indent() << "if (!(that is " << iter->first << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(instance, other)) return true;" << endl; - out << endl; - out << indent() << "return TCollections.Equals(instance, other);" << endl; + out << indent() << "if (ReferenceEquals(instance, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "return TCollections.Equals(instance, other);" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; - out << indent() << "public static int GetHashCode(this " << iter->first << " instance)" << endl; + out << indent() << "public static int GetHashCode(this " << iter->first << " instance)" << '\n'; scope_up(out); - out << indent() << "return TCollections.GetHashCode(instance);" << endl; + out << indent() << "return TCollections.GetHashCode(instance);" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; if(! suppress_deepcopy) { - out << indent() << "public static " << iter->first << nullable_field_suffix(iter->second) << " " << DEEP_COPY_METHOD_NAME << "(this " << iter->first << nullable_field_suffix(iter->second) << " source)" << endl; + out << indent() << "public static " << iter->first << nullable_field_suffix(iter->second) << " " << DEEP_COPY_METHOD_NAME << "(this " << iter->first << nullable_field_suffix(iter->second) << " source)" << '\n'; scope_up(out); - out << indent() << "if (source == null)" << endl; + out << indent() << "if (source == null)" << '\n'; indent_up(); - out << indent() << "return null;" << endl << endl; + out << indent() << "return null;" << '\n' << '\n'; indent_down(); string suffix(""); string tmp_instance = tmp("tmp"); - out << indent() << "var " << tmp_instance << " = new " << iter->first << "(source.Count);" << endl; + if( (target_net_version < 5) && iter->second->is_set()) { + out << indent() << "var " << tmp_instance << " = new " << iter->first << "();" << '\n'; + } else { + out << indent() << "var " << tmp_instance << " = new " << iter->first << "(source.Count);" << '\n'; + } if( iter->second->is_map()) { t_map* tmap = static_cast(iter->second); @@ -723,7 +858,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map bool null_key = type_can_be_null(tmap->get_key_type()); bool null_val = type_can_be_null(tmap->get_val_type()); - out << indent() << "foreach (var pair in source)" << endl; + out << indent() << "foreach (var pair in source)" << '\n'; indent_up(); if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(pair.Key" << copy_key; @@ -742,7 +877,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map out << "pair.Value" << copy_val; } } - out << ");" << endl; + out << ");" << '\n'; indent_down(); } else if( iter->second->is_set() || iter->second->is_list()) { @@ -761,7 +896,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map null_elm = type_can_be_null(tlist->get_elem_type()); } - out << indent() << "foreach (var elem in source)" << endl; + out << indent() << "foreach (var elem in source)" << '\n'; indent_up(); if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(elem" << copy_elm; @@ -774,13 +909,13 @@ void t_netstd_generator::generate_extensions(ostream& out, map out << "elem" << copy_elm; } } - out << ");" << endl; + out << ");" << '\n'; indent_down(); } - out << indent() << "return " << tmp_instance << ";" << endl; + out << indent() << "return " << tmp_instance << ";" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; } } @@ -818,7 +953,7 @@ void t_netstd_generator::generate_netstd_struct(t_struct* tstruct, bool is_excep f_struct.open(f_struct_name.c_str()); reset_indent(); - f_struct << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_struct << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_struct); generate_netstd_struct_definition(f_struct, tstruct, is_exception); @@ -835,7 +970,7 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc start_netstd_namespace(out); } - out << endl; + out << '\n'; generate_netstd_doc(out, tstruct); collect_extensions_types(tstruct); @@ -843,13 +978,14 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc if ((is_serialize_enabled() || is_wcf_enabled()) && !is_exception) { - out << indent() << "[DataContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl; + out << indent() << "[DataContract(Namespace=\"" << wcf_namespace_ << "\")]" << '\n'; } bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end(); string sharp_struct_name = type_name(tstruct, false); + generate_deprecation_attribute(out, tstruct->annotations_); out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << sharp_struct_name << " : "; if (is_exception) @@ -857,8 +993,8 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc out << "TException, "; } - out << "TBase" << endl - << indent() << "{" << endl; + out << "TBase" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -870,10 +1006,10 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc // if the field is required, then we use auto-properties if (!field_is_required((*m_iter))) { - out << indent() << "private " << declare_field(*m_iter, false, true, "_") << endl; + out << indent() << "private " << declare_field(*m_iter, false, true, "_") << '\n'; } } - out << endl; + out << '\n'; bool has_non_required_fields = false; bool has_required_fields = false; @@ -895,19 +1031,19 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc bool generate_isset = has_non_required_fields; if (generate_isset) { - out << endl; + out << '\n'; if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataMember(Order = 1)]" << endl; + out << indent() << "[DataMember(Order = 1)]" << '\n'; } - out << indent() << "public Isset __isset;" << endl; + out << indent() << "public Isset __isset;" << '\n'; if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataContract]" << endl; + out << indent() << "[DataContract]" << '\n'; } - out << indent() << "public struct Isset" << endl - << indent() << "{" << endl; + out << indent() << "public struct Isset" << '\n' + << indent() << "{" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) @@ -919,18 +1055,18 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc { if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataMember]" << endl; + out << indent() << "[DataMember]" << '\n'; } - out << indent() << "public bool " << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << endl; + out << indent() << "public bool " << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (generate_isset && (is_serialize_enabled() || is_wcf_enabled())) { - out << indent() << "#region XmlSerializer support" << endl << endl; + out << indent() << "#region XmlSerializer support" << '\n' << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -939,22 +1075,22 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc // if it is not required, if it has a default value, we need to generate Isset if (!is_required) { - out << indent() << "public bool ShouldSerialize" << prop_name(*m_iter) << "()" << endl - << indent() << "{" << endl; + out << indent() << "public bool ShouldSerialize" << prop_name(*m_iter) << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return __isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << endl; + out << indent() << "return __isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } - out << indent() << "#endregion XmlSerializer support" << endl << endl; + out << indent() << "#endregion XmlSerializer support" << '\n' << '\n'; } } // We always want a default, no argument constructor for Reading - out << indent() << "public " << sharp_struct_name << "()" << endl - << indent() << "{" << endl; + out << indent() << "public " << sharp_struct_name << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) @@ -972,12 +1108,12 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc { print_const_value(out, "this._" + (*m_iter)->get_name(), t, (*m_iter)->get_value(), true, true); // Optionals with defaults are marked set - out << indent() << "this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << " = true;" << endl; + out << indent() << "this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << " = true;" << '\n'; } } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // if we have required fields, we add that CTOR too if (has_required_fields) @@ -999,20 +1135,20 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc out << type_name((*m_iter)->get_type()) << nullable_field_suffix(*m_iter) << " " << normalize_name((*m_iter)->get_name()); } } - out << ") : this()" << endl - << indent() << "{" << endl; + out << ") : this()" << '\n' + << indent() << "{" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (field_is_required(*m_iter)) { - out << indent() << "this." << prop_name(*m_iter) << " = " << normalize_name((*m_iter)->get_name()) << ";" << endl; + out << indent() << "this." << prop_name(*m_iter) << " = " << normalize_name((*m_iter)->get_name()) << ";" << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // DeepCopy() @@ -1032,7 +1168,7 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc generate_netstd_struct_tostring(out, tstruct); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // generate a corresponding WCF fault to wrap the exception if ((is_serialize_enabled() || is_wcf_enabled()) && is_exception) @@ -1050,13 +1186,14 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruct) { - out << endl; - out << indent() << "[DataContract]" << endl; + out << '\n'; + out << indent() << "[DataContract]" << '\n'; bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end(); - out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << type_name(tstruct,false) << "Fault" << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, tstruct->annotations_); + out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << type_name(tstruct,false) << "Fault" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1068,10 +1205,10 @@ void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruc // if the field is required, then we use auto-properties if (!field_is_required((*m_iter))) { - out << indent() << "private " << declare_field(*m_iter, false, true, "_") << endl; + out << indent() << "private " << declare_field(*m_iter, false, true, "_") << '\n'; } } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1079,7 +1216,7 @@ void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruc } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* tstruct, std::string sharp_struct_name) @@ -1091,8 +1228,8 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << indent() << "public " << sharp_struct_name << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public " << sharp_struct_name << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); // return directly if there are only required fields @@ -1100,10 +1237,10 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* out << indent() << "var " << tmp_instance << " = new " << sharp_struct_name << "()"; bool inline_assignment = (target_net_version >= 6); if(inline_assignment) { - out << endl << indent() << "{" << endl; + out << '\n' << indent() << "{" << '\n'; indent_up(); } else { - out << endl; + out << ";\n"; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1118,7 +1255,7 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* if(inline_assignment) { if( null_allowed || (!is_required)) { // = has isset indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; inline_assignment = false; } } @@ -1134,7 +1271,7 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* out << "(" << type_name(ttype) << ")"; } out << "this." << prop_name(*m_iter) << copy_op; - out << (inline_assignment ? "," : ";") << endl; + out << (inline_assignment ? "," : ";") << '\n'; generate_null_check_end( out, *m_iter); if( !is_required) { @@ -1144,29 +1281,29 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* } out << "__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); out << " = this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); - out << (inline_assignment ? "," : ";") << endl; + out << (inline_assignment ? "," : ";") << '\n'; } } if(inline_assignment) { indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } - out << indent() << "return " << tmp_instance << ";" << endl; + out << indent() << "return " << tmp_instance << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "iprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "iprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1177,90 +1314,90 @@ void t_netstd_generator::generate_netstd_struct_reader(ostream& out, t_struct* t { if (field_is_required(*f_iter)) { - out << indent() << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl; + out << indent() << "bool isset_" << (*f_iter)->get_name() << " = false;" << '\n'; } } - out << indent() << "TField field;" << endl - << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "while (true)" << endl - << indent() << "{" << endl; + out << indent() << "TField field;" << '\n' + << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "while (true)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "if (field.Type == TType.Stop)" << endl - << indent() << "{" << endl; + out << indent() << "field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "if (field.Type == TType.Stop)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "break;" << endl; + out << indent() << "break;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl - << indent() << "switch (field.ID)" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' << '\n' + << indent() << "switch (field.ID)" << '\n' + << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool is_required = field_is_required(*f_iter); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ")" << endl - << indent() << "{" << endl; + out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter); if (is_required) { - out << indent() << "isset_" << (*f_iter)->get_name() << " = true;" << endl; + out << indent() << "isset_" << (*f_iter)->get_name() << " = true;" << '\n'; } indent_down(); - out << indent() << "}" << endl - << indent() << "else" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "else" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "break;" << endl; + out << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - out << indent() << "default: " << endl; + out << indent() << "default: " << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "break;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "break;" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (field_is_required((*f_iter))) { - out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl - << indent() << "{" << endl; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl; + out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } indent_down(); - out << indent() << "}" << endl; - out << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "iprot.DecrementRecursionDepth();" << endl; + out << indent() << "iprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } @@ -1284,8 +1421,8 @@ void t_netstd_generator::generate_null_check_begin(ostream& out, t_field* tfield out << "__isset." << get_isset_name(normalize_name(tfield->get_name())); } - out << ")" << endl - << indent() << "{" << endl; + out << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); } } @@ -1297,19 +1434,19 @@ void t_netstd_generator::generate_null_check_end(ostream& out, t_field* tfield) if( null_allowed || (!is_required)) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1317,57 +1454,57 @@ void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* t vector::const_iterator f_iter; string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (fields.size() > 0) { tmpvar = tmp("tmp"); if(target_net_version >= 8) { - out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning disable IDE0017 // simplified init" << '\n'; } - out << indent() << "var " << tmpvar << " = new TField();" << endl; + out << indent() << "var " << tmpvar << " = new TField();" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { generate_null_check_begin( out, *f_iter); - out << indent() << tmpvar << ".Name = \"" << (*f_iter)->get_name() << "\";" << endl - << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl - << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl - << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tmpvar << ".Name = \"" << (*f_iter)->get_name() << "\";" << '\n' + << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << '\n' + << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << '\n' + << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, *f_iter); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_null_check_end(out, *f_iter); } if(target_net_version >= 8) { - out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning restore IDE0017 // simplified init" << '\n'; } } - out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1375,85 +1512,85 @@ void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_st vector::const_iterator f_iter; string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (fields.size() > 0) { tmpvar = tmp("tmp"); if(target_net_version >= 8) { - out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning disable IDE0017 // simplified init" << '\n'; } - out << indent() << "var " << tmpvar << " = new TField();" << endl; + out << indent() << "var " << tmpvar << " = new TField();" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if"; + out << '\n' << indent() << "if"; } else { out << indent() << "else if"; } - out << "(this.__isset." << get_isset_name(normalize_name((*f_iter)->get_name())) << ")" << endl - << indent() << "{" << endl; + out << "(this.__isset." << get_isset_name(normalize_name((*f_iter)->get_name())) << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (" << prop_name(*f_iter) << " != null)" << endl - << indent() << "{" << endl; + out << indent() << "if (" << prop_name(*f_iter) << " != null)" << '\n' + << indent() << "{" << '\n'; indent_up(); } - out << indent() << tmpvar << ".Name = \"" << prop_name(*f_iter) << "\";" << endl - << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl - << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl - << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tmpvar << ".Name = \"" << prop_name(*f_iter) << "\";" << '\n' + << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << '\n' + << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << '\n' + << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, *f_iter); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (null_allowed) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } if(target_net_version >= 8) { - out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning restore IDE0017 // simplified init" << '\n'; } } - out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* tstruct) { string tmpvar = tmp("tmp"); - out << indent() << "public override string ToString()" << endl - << indent() << "{" << endl; + out << indent() << "public override string ToString()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var " << tmpvar << " = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl; + out << indent() << "var " << tmpvar << " = new StringBuilder(\"" << tstruct->get_name() << "(\");" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1464,7 +1601,7 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* { if (!field_is_required((*f_iter))) { - out << indent() << "int " << tmp_count.c_str() << " = 0;" << endl; + out << indent() << "int " << tmp_count.c_str() << " = 0;" << '\n'; useFirstFlag = true; } break; @@ -1479,15 +1616,15 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* if (useFirstFlag && (!had_required)) { - out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { " << tmpvar << ".Append(\", \"); }" << endl; - out << indent() << tmpvar << ".Append(\"" << prop_name(*f_iter) << ": \");" << endl; + out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { " << tmpvar << ".Append(\", \"); }" << '\n'; + out << indent() << tmpvar << ".Append(\"" << prop_name(*f_iter) << ": \");" << '\n'; } else { - out << indent() << tmpvar << ".Append(\", " << prop_name(*f_iter) << ": \");" << endl; + out << indent() << tmpvar << ".Append(\", " << prop_name(*f_iter) << ": \");" << '\n'; } - out << indent() << prop_name(*f_iter) << ".ToString(" << tmpvar << ");" << endl; + out << indent() << prop_name(*f_iter) << ".ToString(" << tmpvar << ");" << '\n'; generate_null_check_end(out, *f_iter); if (is_required) { @@ -1495,10 +1632,10 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* } } - out << indent() << tmpvar << ".Append(')');" << endl - << indent() << "return " << tmpvar << ".ToString();" << endl; + out << indent() << tmpvar << ".Append(')');" << '\n' + << indent() << "return " << tmpvar << ".ToString();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_netstd_generator::generate_netstd_union(t_struct* tunion) @@ -1511,7 +1648,7 @@ void t_netstd_generator::generate_netstd_union(t_struct* tunion) f_union.open(f_union_name.c_str()); reset_indent(); - f_union << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_union << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_union); generate_netstd_union_definition(f_union, tunion); @@ -1526,75 +1663,76 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct // Let's define the class first start_netstd_namespace(out); - out << indent() << "public abstract partial class " << normalize_name(tunion->get_name()) << " : TUnionBase" << endl; - out << indent() << "{" << endl; + generate_deprecation_attribute(out, tunion->annotations_); + out << indent() << "public abstract partial class " << normalize_name(tunion->get_name()) << " : TUnionBase" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "public abstract global::System.Threading.Tasks.Task WriteAsync(TProtocol tProtocol, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "public readonly int Isset;" << endl - << indent() << "public abstract object" << nullable_suffix() <<" Data { get; }" << endl - << indent() << "protected " << normalize_name(tunion->get_name()) << "(int isset)" << endl - << indent() << "{" << endl; + out << indent() << "public abstract global::System.Threading.Tasks.Task WriteAsync(TProtocol tProtocol, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "public readonly int Isset;" << '\n' + << indent() << "public abstract object" << nullable_suffix() <<" Data { get; }" << '\n' + << indent() << "protected " << normalize_name(tunion->get_name()) << "(int isset)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "Isset = isset;" << endl; + out << indent() << "Isset = isset;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; const vector& fields = tunion->get_members(); vector::const_iterator f_iter; - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n'; scope_up(out); if( target_net_version >= 6) { - out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; + out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; + out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; - out << endl; - out << indent() << "if(this.Isset != other.Isset) return false;" << endl; - out << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "if(this.Isset != other.Isset) return false;" << '\n'; + out << '\n'; if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; + out << indent() << "return Isset switch" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << (*f_iter)->get_key() << " => Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ")," << endl; + out << indent() << (*f_iter)->get_key() << " => Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ")," << '\n'; } - out << indent() << "_ => true," << endl; + out << indent() << "_ => true," << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; + out << indent() << "switch (Isset)" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "return Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ");" << endl; + out << indent() << "return Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ");" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return true;" << endl; + out << indent() << "return true;" << '\n'; indent_down(); scope_down(out); } scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public override int GetHashCode()" << endl; - out << indent() << "{" << endl; + out << indent() << "public override int GetHashCode()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; - out << indent() << "{" << endl; + out << indent() << "return Isset switch" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1603,108 +1741,108 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct if( null_coalesce.size() > 0) { out << " ?? 0"; } - out << "," << endl; + out << "," << '\n'; } - out << indent() << "_ => (new ___undefined()).GetHashCode()" << endl; + out << indent() << "_ => (new ___undefined()).GetHashCode()" << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; - out << indent() << "{" << endl; + out << indent() << "switch (Isset)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); out << indent() << "return As_" << (*f_iter)->get_name() << null_coalesce << ".GetHashCode()"; if( null_coalesce.size() > 0) { out << " ?? 0"; } - out << ";" << endl; + out << ";" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return (new ___undefined()).GetHashCode();" << endl; + out << indent() << "return (new ___undefined()).GetHashCode();" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public " << tunion->get_name() << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public " << tunion->get_name() << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; - out << indent() << "{" << endl; + out << indent() << "return Isset switch" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << (*f_iter)->get_key() << " => new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ")," << endl; + out << indent() << (*f_iter)->get_key() << " => new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ")," << '\n'; } - out << indent() << "_ => new ___undefined()" << endl; + out << indent() << "_ => new ___undefined()" << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; - out << indent() << "{" << endl; + out << indent() << "switch (Isset)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "return new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ");" << endl; + out << indent() << "return new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ");" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return new ___undefined();" << endl; + out << indent() << "return new ___undefined();" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } - out << indent() << "public class ___undefined : " << tunion->get_name() << endl; - out << indent() << "{" << endl; + out << indent() << "public class ___undefined : " << tunion->get_name() << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "public override object" << nullable_suffix() <<" Data { get { return null; } }" << endl - << indent() << "public ___undefined() : base(0) {}" << endl << endl; + out << indent() << "public override object" << nullable_suffix() <<" Data { get { return null; } }" << '\n' + << indent() << "public ___undefined() : base(0) {}" << '\n' << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public new ___undefined " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public new ___undefined " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "return new ___undefined();" << endl; + out << indent() << "return new ___undefined();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } t_struct undefined_struct(program_,"___undefined"); generate_netstd_struct_equals(out, &undefined_struct); generate_netstd_struct_hashcode(out, &undefined_struct); - out << indent() << "public override global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public override global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw new TProtocolException( TProtocolException.INVALID_DATA, \"Cannot persist an union type which is not set.\");" << endl; + out << indent() << "throw new TProtocolException( TProtocolException.INVALID_DATA, \"Cannot persist an union type which is not set.\");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1714,128 +1852,128 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct generate_netstd_union_reader(out, tunion); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; end_netstd_namespace(out); } void t_netstd_generator::generate_netstd_union_class(ostream& out, t_struct* tunion, t_field* tfield) { - out << indent() << "public " << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << " As_" << tfield->get_name() << endl; - out << indent() << "{" << endl; + out << indent() << "public " << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << " As_" << tfield->get_name() << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "get" << endl; - out << indent() << "{" << endl; + out << indent() << "get" << '\n'; + out << indent() << "{" << '\n'; indent_up(); out << indent() << "return (" << tfield->get_key() << " == Isset) && (Data != null)" << " ? (" << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << ")Data" << " : default" << (target_net_version >= 6 ? "" : ("(" + type_name(tfield->get_type()) + ")")) - << ";" << endl; + << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl; + out << indent() << "}" << '\n' + << '\n'; - out << indent() << "public class " << normalize_name(tfield->get_name()) << " : " << normalize_name(tunion->get_name()) << endl; - out << indent() << "{" << endl; + out << indent() << "public class " << normalize_name(tfield->get_name()) << " : " << normalize_name(tunion->get_name()) << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "private readonly " << type_name(tfield->get_type()) << " _data;" << endl - << indent() << "public override object" << nullable_suffix() <<" Data { get { return _data; } }" << endl - << indent() << "public " << normalize_name(tfield->get_name()) << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << endl - << indent() << "{" << endl; + out << indent() << "private readonly " << type_name(tfield->get_type()) << " _data;" << '\n' + << indent() << "public override object" << nullable_suffix() <<" Data { get { return _data; } }" << '\n' + << indent() << "public " << normalize_name(tfield->get_name()) << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "this._data = data;" << endl; + out << indent() << "this._data = data;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public new " << normalize_name(tfield->get_name()) << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public new " << normalize_name(tfield->get_name()) << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call(tfield->get_type(), true, needs_typecast, suffix); - out << indent() << "return new " << normalize_name(tfield->get_name()) << "(_data" << copy_op << ");" << endl; + out << indent() << "return new " << normalize_name(tfield->get_name()) << "(_data" << copy_op << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; - out << indent() << "{" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; + out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; + out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; - out << endl; - out << indent() << "return Equals( _data, other.As_" << tfield->get_name() << ");" << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "return Equals( _data, other.As_" << tfield->get_name() << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public override int GetHashCode()" << endl; - out << indent() << "{" << endl; + out << indent() << "public override int GetHashCode()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "return _data.GetHashCode();" << endl; + out << indent() << "return _data.GetHashCode();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ") {" << endl; + out << indent() << "public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ") {" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(struc, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(struc, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; - out << indent() << "var field = new TField()" << endl; - out << indent() << "{" << endl; + out << indent() << "var field = new TField()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "Name = \"" << tfield->get_name() << "\"," << endl - << indent() << "Type = " << type_to_enum(tfield->get_type()) << "," << endl - << indent() << "ID = " << tfield->get_key() << endl; + out << indent() << "Name = \"" << tfield->get_name() << "\"," << '\n' + << indent() << "Type = " << type_to_enum(tfield->get_type()) << "," << '\n' + << indent() << "ID = " << tfield->get_key() << '\n'; indent_down(); - out << indent() << "};" << endl; - out << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "};" << '\n'; + out << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, tfield, "_data", true, false); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* tstruct) { - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl - << indent() << "{" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n' + << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "if (that is not " << type_name(tstruct,false) << " other) return false;" << endl; + out << indent() << "if (that is not " << type_name(tstruct,false) << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << type_name(tstruct,false) << " other)) return false;" << endl; + out << indent() << "if (!(that is " << type_name(tstruct,false) << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; const vector& fields = tstruct->get_members(); @@ -1853,7 +1991,7 @@ void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* t } else { - out << endl; + out << '\n'; out << indent() << "&& "; } if (!field_is_required((*f_iter))) @@ -1879,25 +2017,25 @@ void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* t } if (first) { - out << indent() << "return true;" << endl; + out << indent() << "return true;" << '\n'; } else { - out << ";" << endl; + out << ";" << '\n'; indent_down(); } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_hashcode(ostream& out, t_struct* tstruct) { - out << indent() << "public override int GetHashCode() {" << endl; + out << indent() << "public override int GetHashCode() {" << '\n'; indent_up(); - out << indent() << "int hashcode = 157;" << endl; - out << indent() << "unchecked {" << endl; + out << indent() << "int hashcode = 157;" << '\n'; + out << indent() << "unchecked {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1915,17 +2053,17 @@ void t_netstd_generator::generate_netstd_struct_hashcode(ostream& out, t_struct* else { out << prop_name(*f_iter) << ".GetHashCode()"; } - out << ";" << endl; + out << ";" << '\n'; generate_null_check_end(out, *f_iter); } indent_down(); - out << indent() << "}" << endl; - out << indent() << "return hashcode;" << endl; + out << indent() << "}" << '\n'; + out << indent() << "return hashcode;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_service(t_service* tservice) @@ -1937,13 +2075,13 @@ void t_netstd_generator::generate_service(t_service* tservice) f_service.open(f_service_name.c_str()); reset_indent(); - f_service << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_service << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_service); start_netstd_namespace(f_service); - f_service << indent() << "public partial class " << normalize_name(service_name_) << endl - << indent() << "{" << endl; + f_service << indent() << "public partial class " << normalize_name(service_name_) << '\n' + << indent() << "{" << '\n'; indent_up(); generate_service_interface(f_service, tservice); @@ -1952,7 +2090,7 @@ void t_netstd_generator::generate_service(t_service* tservice) generate_service_helpers(f_service, tservice); indent_down(); - f_service << indent() << "}" << endl; + f_service << indent() << "}" << '\n'; end_netstd_namespace(f_service); f_service.close(); @@ -1970,18 +2108,19 @@ void t_netstd_generator::generate_service_interface(ostream& out, t_service* tse extends_iface = " : " + extends + ".IAsync"; } - //out << endl << endl; + //out << '\n' << '\n'; generate_netstd_doc(out, tservice); if (is_wcf_enabled()) { - out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl; + out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << '\n'; } + generate_deprecation_attribute(out, tservice->annotations_); prepare_member_name_mapping(tservice); - out << indent() << "public interface IAsync" << extends_iface << endl - << indent() << "{" << endl; + out << indent() << "public interface IAsync" << extends_iface << '\n' + << indent() << "{" << '\n'; indent_up(); vector functions = tservice->get_functions(); @@ -1993,34 +2132,42 @@ void t_netstd_generator::generate_service_interface(ostream& out, t_service* tse // if we're using WCF, add the corresponding attributes if (is_wcf_enabled()) { - out << indent() << "[OperationContract]" << endl; + out << indent() << "[OperationContract]" << '\n'; const vector& xceptions = (*f_iter)->get_xceptions()->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "[FaultContract(typeof(" + type_name((*x_iter)->get_type()) + "Fault))]" << endl; + out << indent() << "[FaultContract(typeof(" + type_name((*x_iter)->get_type()) + "Fault))]" << '\n'; } } - generate_deprecation_attribute(out, *f_iter); - out << indent() << function_signature_async(*f_iter) << ";" << endl << endl; + generate_deprecation_attribute(out, (*f_iter)->annotations_); + out << indent() << function_signature_async(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } -void t_netstd_generator::generate_deprecation_attribute(ostream& out, t_function* func) +bool t_netstd_generator::is_deprecated(std::map>& annotations) { - auto iter = func->annotations_.find("deprecated"); - if( func->annotations_.end() != iter) { + auto iter = annotations.find("deprecated"); + return (annotations.end() != iter); +} + +void t_netstd_generator::generate_deprecation_attribute(ostream& out, std::map>& annotations) +{ + auto iter = annotations.find("deprecated"); + if( annotations.end() != iter) { out << indent() << "[Obsolete"; // empty annotation values end up with "1" somewhere, ignore these as well if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { out << "(" << make_csharp_string_literal(iter->second.back()) << ")"; + } else { + out << "(" << make_csharp_string_literal("This code is deprecated.") << ")"; // generic message to prevent CA1041 } - out << "]" << endl; + out << "]" << '\n'; } } @@ -2030,8 +2177,8 @@ void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tserv vector::iterator f_iter; prepare_member_name_mapping(tservice); - out << indent() << "public class InternalStructs" << endl; - out << indent() << "{" << endl; + out << indent() << "public class InternalStructs" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) @@ -2043,7 +2190,7 @@ void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tserv } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2061,22 +2208,23 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi extends_client = "TBaseClient, IDisposable, "; } - out << endl; + out << '\n'; generate_netstd_doc(out, tservice); + generate_deprecation_attribute(out, tservice->annotations_); prepare_member_name_mapping(tservice); - out << indent() << "public class Client : " << extends_client << "IAsync" << endl - << indent() << "{" << endl; + out << indent() << "public class Client : " << extends_client << "IAsync" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "public Client(TProtocol protocol) : this(protocol, protocol)" << endl - << indent() << "{" << endl - << indent() << "}" << endl - << endl - << indent() << "public Client(TProtocol inputProtocol, TProtocol outputProtocol) : base(inputProtocol, outputProtocol)" << endl - << indent() << "{" << endl - << indent() << "}" << endl - << endl; + out << indent() << "public Client(TProtocol protocol) : this(protocol, protocol)" << '\n' + << indent() << "{" << '\n' + << indent() << "}" << '\n' + << '\n' + << indent() << "public Client(TProtocol inputProtocol, TProtocol outputProtocol) : base(inputProtocol, outputProtocol)" << '\n' + << indent() << "{" << '\n' + << indent() << "}" << '\n' + << '\n'; vector functions = tservice->get_functions(); vector::const_iterator functions_iterator; @@ -2087,27 +2235,27 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi string function_name = raw_func_name + (add_async_postfix ? "Async" : ""); // async - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "") << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "") << '\n' + << indent() << "{" << '\n'; indent_up(); out << indent() << "await send_" << function_name << "("; string call_args = argument_list((*functions_iterator)->get_arglist(),false); if(! call_args.empty()) { out << call_args << ", "; } - out << CANCELLATION_TOKEN_NAME << ");" << endl; + out << CANCELLATION_TOKEN_NAME << ");" << '\n'; if(! (*functions_iterator)->is_oneway()) { out << indent() << ((*functions_iterator)->get_returntype()->is_void() ? "" : "return ") - << "await recv_" << function_name << "(" << CANCELLATION_TOKEN_NAME << ");" << endl; + << "await recv_" << function_name << "(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // async send - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "send_", MODE_NO_RETURN) << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "send_", MODE_NO_RETURN) << '\n' + << indent() << "{" << '\n'; indent_up(); string tmpvar = tmp("tmp"); @@ -2115,9 +2263,9 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi out << indent() << "await OutputProtocol.WriteMessageBeginAsync(new TMessage(\"" << raw_func_name << "\", TMessageType." << ((*functions_iterator)->is_oneway() ? "Oneway" : "Call") - << ", SeqId), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << endl - << indent() << "var " << tmpvar << " = new InternalStructs." << argsname << "() {" << endl; + << ", SeqId), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << '\n' + << indent() << "var " << tmpvar << " = new InternalStructs." << argsname << "() {" << '\n'; indent_up(); t_struct* arg_struct = (*functions_iterator)->get_arglist(); @@ -2128,27 +2276,27 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - out << indent() << prop_name(*fld_iter) << " = " << normalize_name((*fld_iter)->get_name(),true) << "," << endl; + out << indent() << prop_name(*fld_iter) << " = " << normalize_name((*fld_iter)->get_name(),true) << "," << '\n'; } indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; - out << indent() << endl - << indent() << "await " << tmpvar << ".WriteAsync(OutputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await OutputProtocol.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await OutputProtocol.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << '\n' + << indent() << "await " << tmpvar << ".WriteAsync(OutputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await OutputProtocol.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await OutputProtocol.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (!(*functions_iterator)->is_oneway()) { // async recv - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "recv_", MODE_NO_ARGS) << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "recv_", MODE_NO_ARGS) << '\n' + << indent() << "{" << '\n'; indent_up(); string resultname = (*functions_iterator)->get_name() + "_result"; @@ -2158,64 +2306,64 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi prepare_member_name_mapping(xs, xs->get_members(), resultname); tmpvar = tmp("tmp"); - out << indent() << endl - << indent() << "var " << tmpvar << " = await InputProtocol.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "if (" << tmpvar << ".Type == TMessageType.Exception)" << endl - << indent() << "{" << endl; + out << indent() << '\n' + << indent() << "var " << tmpvar << " = await InputProtocol.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "if (" << tmpvar << ".Type == TMessageType.Exception)" << '\n' + << indent() << "{" << '\n'; indent_up(); tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = await TApplicationException.ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "throw " << tmpvar << ";" << endl; + out << indent() << "var " << tmpvar << " = await TApplicationException.ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "throw " << tmpvar << ";" << '\n'; indent_down(); tmpvar = tmp("tmp"); - out << indent() << "}" << endl - << endl - << indent() << "var " << tmpvar << " = new InternalStructs." << resultname << "();" << endl - << indent() << "await " << tmpvar << ".ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "var " << tmpvar << " = new InternalStructs." << resultname << "();" << '\n' + << indent() << "await " << tmpvar << ".ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (!(*functions_iterator)->get_returntype()->is_void()) { - out << indent() << "if (" << tmpvar << ".__isset.success)" << endl - << indent() << "{" << endl; + out << indent() << "if (" << tmpvar << ".__isset.success)" << '\n' + << indent() << "{" << '\n'; indent_up(); string nullable_value = nullable_value_access((*functions_iterator)->get_returntype()); - out << indent() << "return " << tmpvar << ".Success" << nullable_value << ";" << endl; + out << indent() << "return " << tmpvar << ".Success" << nullable_value << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } const vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "if (" << tmpvar << ".__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << endl - << indent() << "{" << endl; + out << indent() << "if (" << tmpvar << ".__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw " << tmpvar << "." << prop_name(*x_iter) << nullable_value_access((*x_iter)->get_type()) << ";" << endl; + out << indent() << "throw " << tmpvar << "." << prop_name(*x_iter) << nullable_value_access((*x_iter)->get_type()) << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } if (!(*functions_iterator)->get_returntype()->is_void()) { out << indent() << "throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, \"" - << function_name << " failed: unknown result\");" << endl; + << function_name << " failed: unknown result\");" << '\n'; } cleanup_member_name_mapping(xs); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } cleanup_member_name_mapping(arg_struct); } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2233,14 +2381,14 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi } prepare_member_name_mapping(tservice); - out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << endl - << indent() << "{" << endl; + out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "private readonly IAsync _iAsync;" << endl - << indent() << "private readonly ILogger" << nullable_suffix() << " _logger;" << endl - << endl + out << indent() << "private readonly IAsync _iAsync;" << '\n' + << indent() << "private readonly ILogger" << nullable_suffix() << " _logger;" << '\n' + << '\n' << indent() << "public AsyncProcessor(IAsync iAsync, ILogger" << nullable_suffix() << " logger = default)"; if (!extends.empty()) @@ -2248,101 +2396,101 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi out << " : base(iAsync)"; } - out << endl - << indent() << "{" << endl; + out << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "_iAsync = iAsync ?? throw new ArgumentNullException(nameof(iAsync));" << endl; - out << indent() << "_logger = logger;" << endl; + out << indent() << "_iAsync = iAsync ?? throw new ArgumentNullException(nameof(iAsync));" << '\n'; + out << indent() << "_logger = logger;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string raw_func_name = (*f_iter)->get_name(); - out << indent() << "processMap_[\"" << raw_func_name << "\"] = " << raw_func_name << "_ProcessAsync;" << endl; + out << indent() << "processMap_[\"" << raw_func_name << "\"] = " << raw_func_name << "_ProcessAsync;" << '\n'; } indent_down(); - out << indent() << "}" << endl - << endl; + out << indent() << "}" << '\n' + << '\n'; if (extends.empty()) { - out << indent() << "protected delegate global::System.Threading.Tasks.Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "protected delegate global::System.Threading.Tasks.Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } if (extends.empty()) { out << indent() << "protected Dictionary processMap_ = "; if(target_net_version >= 8) { - out << "[];" << endl; + out << "[];" << '\n'; } else if(target_net_version >= 6) { - out << "new();" << endl; + out << "new();" << '\n'; } else { - out << "new Dictionary();" << endl; + out << "new Dictionary();" << '\n'; } } - out << endl; + out << '\n'; if (extends.empty()) { - out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl - << indent() << "{" << endl; + out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl; + out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; } else { - out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl - << indent() << "{" << endl; + out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl; + out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; } - out << indent() << "{" << endl; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var msg = await iprot.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << endl - << indent() << "processMap_.TryGetValue(msg.Name, out var fn);" << endl - << endl - << indent() << "if (fn == null)" << endl - << indent() << "{" << endl; + out << indent() << "var msg = await iprot.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << '\n' + << indent() << "processMap_.TryGetValue(msg.Name, out var fn);" << '\n' + << '\n' + << indent() << "if (fn == null)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, TType.Struct, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "var x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + msg.Name + \"'\");" << endl - << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await x.WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "return true;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, TType.Struct, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "var x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + msg.Name + \"'\");" << '\n' + << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await x.WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "return true;" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await fn(msg.SeqID, iprot, oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await fn(msg.SeqID, iprot, oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "catch (IOException)" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "catch (IOException)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return false;" << endl; + out << indent() << "return false;" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "return true;" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "return true;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2350,7 +2498,7 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2384,26 +2532,26 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service { (void)tservice; out << indent() << "public async global::System.Threading.Tasks.Task " << tfunction->get_name() - << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; string args = tmp("tmp"); - out << indent() << "var " << args << " = new InternalStructs." << argsname << "();" << endl - << indent() << "await " << args << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << args << " = new InternalStructs." << argsname << "();" << '\n' + << indent() << "await " << args << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; string tmpResult = tmp("tmp"); if (!tfunction->is_oneway()) { - out << indent() << "var " << tmpResult << " = new InternalStructs." << resultname << "();" << endl; + out << indent() << "var " << tmpResult << " = new InternalStructs." << resultname << "();" << '\n'; } - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); t_struct* xs = tfunction->get_xceptions(); @@ -2411,8 +2559,8 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service if (xceptions.size() > 0) { - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); } @@ -2420,9 +2568,8 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service const vector& fields = arg_struct->get_members(); vector::const_iterator f_iter; - bool is_deprecated = (tfunction->annotations_.end() != tfunction->annotations_.find("deprecated")); - if( is_deprecated) { - out << indent() << "#pragma warning disable CS0618,CS0612" << endl; + if( is_deprecated(tfunction->annotations_)) { + out << indent() << "#pragma warning disable CS0618,CS0612" << '\n'; } out << indent(); @@ -2457,10 +2604,10 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service out << ", "; } - out << "" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << "" << CANCELLATION_TOKEN_NAME << ");" << '\n'; - if( is_deprecated) { - out << indent() << "#pragma warning restore CS0618,CS0612" << endl; + if( is_deprecated(tfunction->annotations_)) { + out << indent() << "#pragma warning restore CS0618,CS0612" << '\n'; } vector::const_iterator x_iter; @@ -2470,76 +2617,76 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service if (xceptions.size() > 0) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { string tmpex = tmp("tmp"); - out << indent() << "catch (" << type_name((*x_iter)->get_type()) << " " << tmpex << ")" << endl - << indent() << "{" << endl; + out << indent() << "catch (" << type_name((*x_iter)->get_type()) << " " << tmpex << ")" << '\n' + << indent() << "{" << '\n'; if (!tfunction->is_oneway()) { indent_up(); - out << indent() << tmpResult << "." << prop_name(*x_iter) << " = " << tmpex << ";" << endl; + out << indent() << tmpResult << "." << prop_name(*x_iter) << " = " << tmpex << ";" << '\n'; indent_down(); } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } if (!tfunction->is_oneway()) { out << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.Reply, seqid), " << CANCELLATION_TOKEN_NAME << "); " << endl - << indent() << "await " << tmpResult << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + << tfunction->get_name() << "\", TMessageType.Reply, seqid), " << CANCELLATION_TOKEN_NAME << "); " << '\n' + << indent() << "await " << tmpResult << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); cleanup_member_name_mapping(xs); string tmpex = tmp("tmp"); - out << indent() << "}" << endl - << indent() << "catch (TTransportException)" << endl - << indent() << "{" << endl - << indent() << " throw;" << endl - << indent() << "}" << endl - << indent() << "catch (Exception " << tmpex << ")" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "catch (TTransportException)" << '\n' + << indent() << "{" << '\n' + << indent() << " throw;" << '\n' + << indent() << "}" << '\n' + << indent() << "catch (Exception " << tmpex << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = $\"Error occurred in {GetType().FullName}: {" << tmpex << ".Message}\";" << endl; - out << indent() << "if(_logger != null)" << endl; + out << indent() << "var " << tmpvar << " = $\"Error occurred in {GetType().FullName}: {" << tmpex << ".Message}\";" << '\n'; + out << indent() << "if ((_logger != null) && _logger.IsEnabled(LogLevel.Error))" << '\n'; indent_up(); - out << indent() << "_logger.LogError(\"{Exception}, {Message}\", " << tmpex << ", " << tmpvar << ");" << endl; + out << indent() << "_logger.LogError(\"{Exception}, {Message}\", " << tmpex << ", " << tmpvar << ");" << '\n'; indent_down(); - out << indent() << "else" << endl; + out << indent() << "else" << '\n'; indent_up(); - out << indent() << "Console.Error.WriteLine(" << tmpvar << ");" << endl; + out << indent() << "Console.Error.WriteLine(" << tmpvar << ");" << '\n'; indent_down(); if (tfunction->is_oneway()) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl + out << indent() << "var " << tmpvar << " = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << '\n' << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.Exception, seqid), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await " << tmpvar << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + << "\", TMessageType.Exception, seqid), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await " << tmpvar << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_union_reader(ostream& out, t_struct* tunion) @@ -2548,76 +2695,76 @@ void t_netstd_generator::generate_netstd_union_reader(ostream& out, t_struct* tu const vector& fields = tunion->get_members(); vector::const_iterator f_iter; - out << indent() << "public static async Task<" << tunion->get_name() << "> ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public static async Task<" << tunion->get_name() << "> ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; scope_up(out); - out << indent() << "iprot.IncrementRecursionDepth();" << endl; - out << indent() << "try" << endl; + out << indent() << "iprot.IncrementRecursionDepth();" << '\n'; + out << indent() << "try" << '\n'; scope_up(out); string tmpRetval = tmp("tmp"); - out << indent() << tunion->get_name() << " " << tmpRetval << ";" << endl; - out << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "TField field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tunion->get_name() << " " << tmpRetval << ";" << '\n'; + out << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "TField field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; // we cannot have the first field be a stop -- we must have a single field defined - out << indent() << "if (field.Type == TType.Stop)" << endl; + out << indent() << "if (field.Type == TType.Stop)" << '\n'; scope_up(out); - out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "" << tmpRetval << " = new ___undefined();" << endl; + out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "" << tmpRetval << " = new ___undefined();" << '\n'; scope_down(out); - out << indent() << "else" << endl; + out << indent() << "else" << '\n'; scope_up(out); - out << indent() << "switch (field.ID)" << endl; + out << indent() << "switch (field.ID)" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); string tmpvar = tmp("tmp"); - out << indent() << type_name((*f_iter)->get_type()) << " " << tmpvar << ";" << endl; + out << indent() << type_name((*f_iter)->get_type()) << " " << tmpvar << ";" << '\n'; generate_deserialize_field(out, (*f_iter), tmpvar, true); - out << indent() << tmpRetval << " = new " << (*f_iter)->get_name() << "(" << tmpvar << ");" << endl; + out << indent() << tmpRetval << " = new " << (*f_iter)->get_name() << "(" << tmpvar << ");" << '\n'; indent_down(); - out << indent() << "} else { " << endl << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" - << endl << indent() << " " << tmpRetval << " = new ___undefined();" << endl << indent() << "}" << endl - << indent() << "break;" << endl; + out << indent() << "} else { " << '\n' << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" + << '\n' << indent() << " " << tmpRetval << " = new ___undefined();" << '\n' << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - out << indent() << "default: " << endl; + out << indent() << "default: " << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl << indent() - << tmpRetval << " = new ___undefined();" << endl; - out << indent() << "break;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n' << indent() + << tmpRetval << " = new ___undefined();" << '\n'; + out << indent() << "break;" << '\n'; indent_down(); scope_down(out); - out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; - out << indent() << "if ((await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ")).Type != TType.Stop)" << endl; + out << indent() << "if ((await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ")).Type != TType.Stop)" << '\n'; scope_up(out); - out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl; + out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << '\n'; scope_down(out); // end of else for TStop scope_down(out); - out << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "return " << tmpRetval << ";" << endl; + out << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "return " << tmpRetval << ";" << '\n'; indent_down(); scope_down(out); - out << indent() << "finally" << endl; + out << indent() << "finally" << '\n'; scope_up(out); - out << indent() << "iprot.DecrementRecursionDepth();" << endl; + out << indent() << "iprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless) @@ -2698,7 +2845,7 @@ void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfiel { out << "ReadI32Async(" << CANCELLATION_TOKEN_NAME << ");"; } - out << endl; + out << '\n'; } else { @@ -2710,18 +2857,18 @@ void t_netstd_generator::generate_deserialize_struct(ostream& out, t_struct* tst { if (is_union_enabled() && tstruct->is_union()) { - out << indent() << prefix << " = await " << type_name(tstruct) << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << prefix << " = await " << type_name(tstruct) << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else { - out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl - << indent() << "await " << prefix << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << prefix << " = new " << type_name(tstruct) << "();" << '\n' + << indent() << "await " << prefix << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } } void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { - out << indent() << "{" << endl; + out << indent() << "{" << '\n'; indent_up(); string obj; @@ -2741,21 +2888,25 @@ void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* tt if (ttype->is_map()) { - out << indent() << "var " << obj << " = await iprot.ReadMapBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadMapBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "var " << obj << " = await iprot.ReadSetBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadSetBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "var " << obj << " = await iprot.ReadListBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadListBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } - out << indent() << prefix << " = new " << type_name(ttype) << "(" << obj << ".Count);" << endl; + if( (target_net_version < 5) && ttype->is_set()) { + out << indent() << prefix << " = new " << type_name(ttype) << "();" << '\n'; + } else { + out << indent() << prefix << " = new " << type_name(ttype) << "(" << obj << ".Count);" << '\n'; + } string i = tmp("_i"); - out << indent() << "for(int " << i << " = 0; " << i << " < " << obj << ".Count; ++" << i << ")" << endl - << indent() << "{" << endl; + out << indent() << "for(int " << i << " = 0; " << i << " < " << obj << ".Count; ++" << i << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); if (ttype->is_map()) @@ -2772,23 +2923,23 @@ void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* tt } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (ttype->is_map()) { - out << indent() << "await iprot.ReadMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "await iprot.ReadSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "await iprot.ReadListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_netstd_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) @@ -2799,13 +2950,13 @@ void t_netstd_generator::generate_deserialize_map_element(ostream& out, t_map* t t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - out << indent() << declare_field(&fkey, false, false) << endl; - out << indent() << declare_field(&fval, false, false) << endl; + out << indent() << declare_field(&fkey, false, false) << '\n'; + out << indent() << declare_field(&fval, false, false) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - out << indent() << prefix << "[" << key << "] = " << val << ";" << endl; + out << indent() << prefix << "[" << key << "] = " << val << ";" << '\n'; } void t_netstd_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) @@ -2813,11 +2964,11 @@ void t_netstd_generator::generate_deserialize_set_element(ostream& out, t_set* t string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - out << indent() << declare_field(&felem, false, false) << endl; + out << indent() << declare_field(&felem, false, false) << '\n'; generate_deserialize_field(out, &felem); - out << indent() << prefix << ".Add(" << elem << ");" << endl; + out << indent() << prefix << ".Add(" << elem << ");" << '\n'; } void t_netstd_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix) @@ -2825,11 +2976,11 @@ void t_netstd_generator::generate_deserialize_list_element(ostream& out, t_list* string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - out << indent() << declare_field(&felem, false, false) << endl; + out << indent() << declare_field(&felem, false, false) << '\n'; generate_deserialize_field(out, &felem); - out << indent() << prefix << ".Add(" << elem << ");" << endl; + out << indent() << prefix << ".Add(" << elem << ");" << '\n'; } void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless, bool allow_nullable) @@ -2904,7 +3055,7 @@ void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, { out << "WriteI32Async((int)" << name << ", " << CANCELLATION_TOKEN_NAME << ");"; } - out << endl; + out << '\n'; } else { @@ -2915,7 +3066,7 @@ void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, void t_netstd_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << "await " << prefix << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await " << prefix << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) @@ -2924,18 +3075,18 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp { out << indent() << "await oprot.WriteMapBeginAsync(new TMap(" << type_to_enum(static_cast(ttype)->get_key_type()) << ", " << type_to_enum(static_cast(ttype)->get_val_type()) << ", " << prefix - << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << endl; + << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { out << indent() << "await oprot.WriteSetBeginAsync(new TSet(" << type_to_enum(static_cast(ttype)->get_elem_type()) - << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << endl; + << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { out << indent() << "await oprot.WriteListBeginAsync(new TList(" << type_to_enum(static_cast(ttype)->get_elem_type()) << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" - << endl; + << '\n'; } string iter = tmp("_iter"); @@ -2955,8 +3106,8 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp << " in " << prefix << ")"; } - out << endl; - out << indent() << "{" << endl; + out << '\n'; + out << indent() << "{" << '\n'; indent_up(); if (ttype->is_map()) @@ -2973,19 +3124,19 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (ttype->is_map()) { - out << indent() << "await oprot.WriteMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "await oprot.WriteSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "await oprot.WriteListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } } @@ -3018,8 +3169,9 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, { if ((is_serialize_enabled() || is_wcf_enabled()) && isPublic) { - out << indent() << "[DataMember(Order = 0)]" << endl; + out << indent() << "[DataMember(Order = 0)]" << '\n'; } + generate_deprecation_attribute(out, tfield->annotations_); out << indent() << (isPublic ? "public " : "private ") @@ -3036,37 +3188,37 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, if( (target_net_version >= 6) && (!force_member_nullable(tfield))) { out << initialize_field(tfield) << ";"; } - out << endl; + out << '\n'; } else { - out << endl - << indent() << "{" << endl; + out << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "get" << endl - << indent() << "{" << endl; + out << indent() << "get" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return " << fieldPrefix + tfield->get_name() << ";" << endl; + out << indent() << "return " << fieldPrefix + tfield->get_name() << ";" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "set" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "set" << '\n' + << indent() << "{" << '\n'; indent_up(); if (generateIsset) { - out << indent() << "__isset." << get_isset_name(normalize_name(tfield->get_name())) << " = true;" << endl; + out << indent() << "__isset." << get_isset_name(normalize_name(tfield->get_name())) << " = true;" << '\n'; } - out << indent() << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl; + out << indent() << "this." << fieldPrefix + tfield->get_name() << " = value;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << endl; + out << '\n'; } string t_netstd_generator::make_csharp_string_literal( string const& value) @@ -3749,14 +3901,14 @@ string t_netstd_generator::type_to_enum(t_type* type) void t_netstd_generator::generate_netstd_docstring_comment(ostream& out, string contents) { - docstring_comment(out, "/// " + endl, "/// ", contents, "/// " + endl); + docstring_comment(out, "/// " + string("\n"), "/// ", contents, "/// " + string("\n")); } void t_netstd_generator::generate_netstd_doc(ostream& out, t_field* field) { if (field->get_type()->is_enum()) { - string combined_message = field->get_doc() + endl + "get_type()) + "\"/>"; + string combined_message = field->get_doc() + "\n" + "get_type()) + "\"/>"; generate_netstd_docstring_comment(out, combined_message); } else @@ -3783,7 +3935,7 @@ void t_netstd_generator::generate_netstd_doc(ostream& out, t_function* tfunction for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) { t_field* p = *p_iter; - ps << endl << "get_name() << "\">"; + ps << '\n' << "get_name() << "\">"; if (p->has_doc()) { string str = p->get_doc(); @@ -3796,7 +3948,7 @@ void t_netstd_generator::generate_netstd_doc(ostream& out, t_function* tfunction docstring_comment(out, "", "/// ", - "" + endl + tfunction->get_doc() + "" + ps.str(), + "" + string("\n") + tfunction->get_doc() + "" + ps.str(), ""); } } @@ -3818,11 +3970,11 @@ void t_netstd_generator::docstring_comment(ostream& out, const string& comment_s // Just prnt a newline when the line & prefix are empty. if (strlen(line) == 0 && line_prefix == "" && !docs.eof()) { - out << endl; + out << '\n'; } else if (strlen(line) > 0 || !docs.eof()) { // skip the empty last line - out << indent() << line_prefix << line << endl; + out << indent() << line_prefix << line << '\n'; } } if (comment_end != "") @@ -3854,8 +4006,9 @@ THRIFT_REGISTER_GENERATOR( " serial: Add serialization support to generated classes.\n" " union: Use new union typing, which includes a static read function for union types.\n" " pascal: Generate Pascal Case property names according to Microsoft naming convention.\n" - " net6: Enable features that require net6 and C# 8 or higher.\n" " net8: Enable features that require net8 and C# 12 or higher.\n" + " net9: Enable features that require net9 and C# 13 or higher.\n" + " net10: Enable features that require net10 and C# 14 or higher.\n" " no_deepcopy: Suppress generation of " + DEEP_COPY_METHOD_NAME + "() method.\n" " async_postfix: Append \"Async\" to all service methods (maintains compatibility with existing code).\n" ) diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h index ff3cfb1264c..4623b122862 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h @@ -44,8 +44,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string DEEP_COPY_METHOD_NAME = "DeepCopy"; static const string CANCELLATION_TOKEN_NAME = "cancellationToken"; @@ -106,7 +104,7 @@ class t_netstd_generator : public t_oop_generator void generate_netstd_union_reader(ostream& out, t_struct* tunion); void generate_function_helpers(ostream& out, t_function* tfunction); void generate_service_interface(ostream& out, t_service* tservice); - void generate_deprecation_attribute(ostream& out, t_function* func); + void generate_deprecation_attribute(ostream& out, std::map>& annotations); void generate_service_helpers(ostream& out, t_service* tservice); void generate_service_client(ostream& out, t_service* tservice); void generate_service_server(ostream& out, t_service* tservice); @@ -165,7 +163,7 @@ class t_netstd_generator : public t_oop_generator comment += " */\n"; return comment; } - + private: string namespace_name_; @@ -177,20 +175,20 @@ class t_netstd_generator : public t_oop_generator bool wcf_; bool use_pascal_case_properties; bool suppress_deepcopy; - int target_net_version; // 0 = any, 6 = net6, 8 = net8 + int target_net_version; // 0 = any, 6 = net6, 8 = net8, etc. bool add_async_postfix; const std::string CSHARP_KEYWORDS[101] = { // C# keywords - "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", - "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", - "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", - "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", - "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", - "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", - "using", "virtual", "void", "volatile", "while", + "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", + "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", + "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", + "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", + "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", + "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", + "using", "virtual", "void", "volatile", "while", // C# contextual keywords - "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", + "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "remove", "select", "set", "value", "var", "when", "where", "yield" }; @@ -199,7 +197,7 @@ class t_netstd_generator : public t_oop_generator vector member_mapping_scopes; map collected_extension_types; map checked_extension_types; - + string normalize_name(string name, bool is_arg_name = false); string make_valid_csharp_identifier(string const& fromName); string make_csharp_string_literal( string const& value); @@ -220,6 +218,8 @@ class t_netstd_generator : public t_oop_generator string initialize_field(t_field* tfield); void pragmas_and_directives(ostream& out); + bool any_deprecations(); + bool is_deprecated(std::map>& annotations); bool is_nullable_type(t_type* ttype); bool force_member_nullable(t_field* tfield); // see there string nullable_suffix(); // unconditionally diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc index 5f9b80cf5ec..34dda402a1a 100644 --- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * OCaml code generator. * @@ -241,10 +239,10 @@ void t_ocaml_generator::init_generator() { f_consts_.open(f_consts_name.c_str()); // Print header - f_types_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_types_i_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_consts_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl << "open " - << capitalize(program_name_) << "_types" << endl; + f_types_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_types_i_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_consts_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n' << "open " + << capitalize(program_name_) << "_types" << '\n'; } /** @@ -277,9 +275,9 @@ t_ocaml_generator::~t_ocaml_generator() { */ void t_ocaml_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << indent() << "type " << decapitalize(ttypedef->get_symbolic()) << " = " - << render_ocaml_type(ttypedef->get_type()) << endl << endl; + << render_ocaml_type(ttypedef->get_type()) << '\n' << '\n'; f_types_i_ << indent() << "type " << decapitalize(ttypedef->get_symbolic()) << " = " - << render_ocaml_type(ttypedef->get_type()) << endl << endl; + << render_ocaml_type(ttypedef->get_type()) << '\n' << '\n'; } /** @@ -289,46 +287,46 @@ void t_ocaml_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_ocaml_generator::generate_enum(t_enum* tenum) { - indent(f_types_) << "module " << capitalize(tenum->get_name()) << " = " << endl << "struct" - << endl; - indent(f_types_i_) << "module " << capitalize(tenum->get_name()) << " : " << endl << "sig" - << endl; + indent(f_types_) << "module " << capitalize(tenum->get_name()) << " = " << '\n' << "struct" + << '\n'; + indent(f_types_i_) << "module " << capitalize(tenum->get_name()) << " : " << '\n' << "sig" + << '\n'; indent_up(); - indent(f_types_) << "type t = " << endl; - indent(f_types_i_) << "type t = " << endl; + indent(f_types_) << "type t = " << '\n'; + indent(f_types_i_) << "type t = " << '\n'; indent_up(); vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << name << endl; - indent(f_types_i_) << "| " << name << endl; + indent(f_types_) << "| " << name << '\n'; + indent(f_types_i_) << "| " << name << '\n'; } indent_down(); - indent(f_types_) << "let to_i = function" << endl; - indent(f_types_i_) << "val to_i : t -> Int32.t" << endl; + indent(f_types_) << "let to_i = function" << '\n'; + indent(f_types_i_) << "val to_i : t -> Int32.t" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << name << " -> " << value << "l" << endl; + indent(f_types_) << "| " << name << " -> " << value << "l" << '\n'; } indent_down(); - indent(f_types_) << "let of_i = function" << endl; - indent(f_types_i_) << "val of_i : Int32.t -> t" << endl; + indent(f_types_) << "let of_i = function" << '\n'; + indent(f_types_i_) << "val of_i : Int32.t -> t" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << value << "l -> " << name << endl; + indent(f_types_) << "| " << value << "l -> " << name << '\n'; } - indent(f_types_) << "| _ -> raise Thrift_error" << endl; + indent(f_types_) << "| _ -> raise Thrift_error" << '\n'; indent_down(); indent_down(); - indent(f_types_) << "end" << endl; - indent(f_types_i_) << "end" << endl; + indent(f_types_) << "end" << '\n'; + indent(f_types_i_) << "end" << '\n'; } /** @@ -339,7 +337,7 @@ void t_ocaml_generator::generate_const(t_const* tconst) { string name = decapitalize(tconst->get_name()); t_const_value* value = tconst->get_value(); - indent(f_consts_) << "let " << name << " = " << render_const_value(type, value) << endl << endl; + indent(f_consts_) << "let " << name << " = " << render_const_value(type, value) << '\n' << '\n'; } /** @@ -395,9 +393,9 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_struct() || type->is_xception()) { string cname = type_name(type); string ct = tmp("_c"); - out << endl; + out << '\n'; indent_up(); - indent(out) << "(let " << ct << " = new " << cname << " in" << endl; + indent(out) << "(let " << ct << " = new " << cname << " in" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -417,7 +415,7 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) out << indent(); out << ct << "#set_" << fname << " "; out << render_const_value(field_type, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } indent(out) << ct << ")"; indent_down(); @@ -428,14 +426,14 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) const map& val = value->get_map(); map::const_iterator v_iter; string hm = tmp("_hm"); - out << endl; + out << '\n'; indent_up(); - indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << endl; + indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << '\n'; indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string key = render_const_value(ktype, v_iter->first); string val = render_const_value(vtype, v_iter->second); - indent(out) << "Hashtbl.add " << hm << " " << key << " " << val << ";" << endl; + indent(out) << "Hashtbl.add " << hm << " " << key << " " << val << ";" << '\n'; } indent(out) << hm << ")"; indent_down(); @@ -443,14 +441,14 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_list()) { t_type* etype; etype = ((t_list*)type)->get_elem_type(); - out << "[" << endl; + out << "[" << '\n'; indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent(); out << render_const_value(etype, *v_iter); - out << ";" << endl; + out << ";" << '\n'; } indent_down(); indent(out) << "]"; @@ -459,15 +457,15 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) const vector& val = value->get_list(); vector::const_iterator v_iter; string hm = tmp("_hm"); - indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << endl; + indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << '\n'; indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "Hashtbl.add " << hm << " " << val << " true;" << endl; + indent(out) << "Hashtbl.add " << hm << " " << val << " true;" << '\n'; } - indent(out) << hm << ")" << endl; + indent(out) << hm << ")" << '\n'; indent_down(); - out << endl; + out << '\n'; } else { throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name(); } @@ -503,15 +501,15 @@ void t_ocaml_generator::generate_ocaml_method_copy(ostream& out, const vector::const_iterator m_iter; /* Create a copy of the current object */ - indent(out) << "method copy =" << endl; + indent(out) << "method copy =" << '\n'; indent_up(); indent_up(); - indent(out) << "let _new = Oo.copy self in" << endl; + indent(out) << "let _new = Oo.copy self in" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) generate_ocaml_member_copy(out, *m_iter); indent_down(); - indent(out) << "_new" << endl; + indent(out) << "_new" << '\n'; indent_down(); } @@ -564,10 +562,10 @@ void t_ocaml_generator::generate_ocaml_member_copy(ostream& out, t_field* tmembe if (copy_of != grab_field) { indent(out); if (!struct_member_persistent(tmember)) { - out << "if _" << mname << " <> None then" << endl; + out << "if _" << mname << " <> None then" << '\n'; indent(out) << " "; } - out << "_new#set_" << mname << " " << copy_of << ";" << endl; + out << "_new#set_" << mname << " " << copy_of << ";" << '\n'; } } @@ -582,24 +580,24 @@ void t_ocaml_generator::generate_ocaml_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; string tname = type_name(tstruct); - indent(out) << "class " << tname << " =" << endl; - indent(out) << "object (self)" << endl; + indent(out) << "class " << tname << " =" << '\n'; + indent(out) << "object (self)" << '\n'; indent_up(); if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_ocaml_struct_member(out, tname, (*m_iter)); - out << endl; + out << '\n'; } } generate_ocaml_method_copy(out, members); generate_ocaml_struct_writer(out, tstruct); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; if (is_exception) { - indent(out) << "exception " << capitalize(tname) << " of " << tname << endl; + indent(out) << "exception " << capitalize(tname) << " of " << tname << '\n'; } generate_ocaml_struct_reader(out, tstruct); @@ -621,37 +619,37 @@ void t_ocaml_generator::generate_ocaml_struct_member(ostream& out, t_const_value* val = tmember->get_value(); if (val) { if (struct_member_persistent(tmember)) - out << " = " << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << " = " << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; else out << " option = Some " << render_const_value(tmember->get_type(), tmember->get_value()) - << endl; + << '\n'; } else { // assert(!struct_member_persistent(tmember)) - out << " option = None" << endl; + out << " option = None" << '\n'; } if (struct_member_persistent(tmember)) { - indent(out) << "method get_" << mname << " = Some _" << mname << endl; - indent(out) << "method grab_" << mname << " = _" << mname << endl; - indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- " << x << endl; + indent(out) << "method get_" << mname << " = Some _" << mname << '\n'; + indent(out) << "method grab_" << mname << " = _" << mname << '\n'; + indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- " << x << '\n'; } else { - indent(out) << "method get_" << mname << " = _" << mname << endl; + indent(out) << "method get_" << mname << " = _" << mname << '\n'; indent(out) << "method grab_" << mname << " = match _" << mname << " with None->raise (Field_empty \"" << tname << "." << mname << "\") | Some " - << x << " -> " << x << endl; + << x << " -> " << x << '\n'; indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- Some " << x - << endl; - indent(out) << "method unset_" << mname << " = _" << mname << " <- None" << endl; + << '\n'; + indent(out) << "method unset_" << mname << " = _" << mname << " <- None" << '\n'; } indent(out) << "method reset_" << mname << " = _" << mname << " <- "; if (val) { if (struct_member_persistent(tmember)) - out << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; else - out << "Some " << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << "Some " << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; } else { - out << "None" << endl; + out << "None" << '\n'; } } @@ -719,8 +717,8 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; string tname = type_name(tstruct); - indent(out) << "class " << tname << " :" << endl; - indent(out) << "object ('a)" << endl; + indent(out) << "class " << tname << " :" << '\n'; + indent(out) << "object ('a)" << '\n'; indent_up(); @@ -729,24 +727,24 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out, for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string mname = decapitalize((*m_iter)->get_name()); string type = render_ocaml_type((*m_iter)->get_type()); - indent(out) << "method get_" << mname << " : " << type << " option" << endl; - indent(out) << "method grab_" << mname << " : " << type << endl; - indent(out) << "method set_" << mname << " : " << type << " -> unit" << endl; + indent(out) << "method get_" << mname << " : " << type << " option" << '\n'; + indent(out) << "method grab_" << mname << " : " << type << '\n'; + indent(out) << "method set_" << mname << " : " << type << " -> unit" << '\n'; if (!struct_member_persistent(*m_iter)) - indent(out) << "method unset_" << mname << " : unit" << endl; - indent(out) << "method reset_" << mname << " : unit" << endl; + indent(out) << "method unset_" << mname << " : unit" << '\n'; + indent(out) << "method reset_" << mname << " : unit" << '\n'; } } - indent(out) << "method copy : 'a" << endl; - indent(out) << "method write : Protocol.t -> unit" << endl; + indent(out) << "method copy : 'a" << '\n'; + indent(out) << "method write : Protocol.t -> unit" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; if (is_exception) { - indent(out) << "exception " << capitalize(tname) << " of " << tname << endl; + indent(out) << "exception " << capitalize(tname) << " of " << tname << '\n'; } - indent(out) << "val read_" << tname << " : Protocol.t -> " << tname << endl; + indent(out) << "val read_" << tname << " : Protocol.t -> " << tname << '\n'; } /** @@ -759,55 +757,55 @@ void t_ocaml_generator::generate_ocaml_struct_reader(ostream& out, t_struct* tst string str = tmp("_str"); string t = tmp("_t"); string id = tmp("_id"); - indent(out) << "let rec read_" << sname << " (iprot : Protocol.t) =" << endl; + indent(out) << "let rec read_" << sname << " (iprot : Protocol.t) =" << '\n'; indent_up(); - indent(out) << "let " << str << " = new " << sname << " in" << endl; + indent(out) << "let " << str << " = new " << sname << " in" << '\n'; indent_up(); - indent(out) << "ignore(iprot#readStructBegin);" << endl; + indent(out) << "ignore(iprot#readStructBegin);" << '\n'; // Loop over reading in fields - indent(out) << "(try while true do" << endl; + indent(out) << "(try while true do" << '\n'; indent_up(); indent_up(); // Read beginning field marker - indent(out) << "let (_," << t << "," << id << ") = iprot#readFieldBegin in" << endl; + indent(out) << "let (_," << t << "," << id << ") = iprot#readFieldBegin in" << '\n'; // Check for field STOP marker and break - indent(out) << "if " << t << " = Protocol.T_STOP then" << endl; + indent(out) << "if " << t << " = Protocol.T_STOP then" << '\n'; indent_up(); - indent(out) << "raise Break" << endl; + indent(out) << "raise Break" << '\n'; indent_down(); - indent(out) << "else ();" << endl; + indent(out) << "else ();" << '\n'; - indent(out) << "(match " << id << " with " << endl; + indent(out) << "(match " << id << " with " << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "| " << (*f_iter)->get_key() << " -> ("; - out << "if " << t << " = " << type_to_enum((*f_iter)->get_type()) << " then" << endl; + out << "if " << t << " = " << type_to_enum((*f_iter)->get_type()) << " then" << '\n'; indent_up(); indent_up(); generate_deserialize_field(out, *f_iter, str); indent_down(); - out << indent() << "else" << endl << indent() << " iprot#skip " << t << ")" << endl; + out << indent() << "else" << '\n' << indent() << " iprot#skip " << t << ")" << '\n'; indent_down(); } // In the default case we skip the field out << indent() << "| _ -> " - << "iprot#skip " << t << ");" << endl; + << "iprot#skip " << t << ");" << '\n'; indent_down(); // Read field end marker - indent(out) << "iprot#readFieldEnd;" << endl; + indent(out) << "iprot#readFieldEnd;" << '\n'; indent_down(); - indent(out) << "done; ()" << endl; + indent(out) << "done; ()" << '\n'; indent_down(); - indent(out) << "with Break -> ());" << endl; + indent(out) << "with Break -> ());" << '\n'; - indent(out) << "iprot#readStructEnd;" << endl; + indent(out) << "iprot#readStructEnd;" << '\n'; - indent(out) << str << endl << endl; + indent(out) << str << '\n' << '\n'; indent_down(); indent_down(); } @@ -819,9 +817,9 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst string str = tmp("_str"); string f = tmp("_f"); - indent(out) << "method write (oprot : Protocol.t) =" << endl; + indent(out) << "method write (oprot : Protocol.t) =" << '\n'; indent_up(); - indent(out) << "oprot#writeStructBegin \"" << name << "\";" << endl; + indent(out) << "oprot#writeStructBegin \"" << name << "\";" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* tmember = (*f_iter); @@ -835,10 +833,10 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst // Avoid redundant encoding of members having default values. indent(out) << "(match " << mname << " with " << render_const_value(tmember->get_type(), tmember->get_value()) << " -> () | " - << _v << " -> " << endl; + << _v << " -> " << '\n'; } else { _v = mname; - indent(out) << "(" << endl; + indent(out) << "(" << '\n'; } } else { @@ -853,12 +851,12 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst out << " | Some " << render_const_value(tmember->get_type(), tmember->get_value()) << " -> ()"; } - out << " | Some _v -> " << endl; + out << " | Some _v -> " << '\n'; } else { - out << endl; + out << '\n'; indent(out) << "| None -> raise (Field_empty \"" << type_name(tstruct) << "." << mname - << "\")" << endl; - indent(out) << "| Some _v -> " << endl; + << "\")" << '\n'; + indent(out) << "| Some _v -> " << '\n'; } _v = "_v"; @@ -866,20 +864,20 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst indent_up(); // Write field header indent(out) << "oprot#writeFieldBegin(\"" << tmember->get_name() << "\"," - << type_to_enum(tmember->get_type()) << "," << tmember->get_key() << ");" << endl; + << type_to_enum(tmember->get_type()) << "," << tmember->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, tmember, _v); // Write field closer - indent(out) << "oprot#writeFieldEnd" << endl; + indent(out) << "oprot#writeFieldEnd" << '\n'; indent_down(); - indent(out) << ");" << endl; + indent(out) << ");" << '\n'; } // Write the struct map - out << indent() << "oprot#writeFieldStop;" << endl << indent() << "oprot#writeStructEnd" << endl; + out << indent() << "oprot#writeFieldStop;" << '\n' << indent() << "oprot#writeStructEnd" << '\n'; indent_down(); } @@ -895,19 +893,19 @@ void t_ocaml_generator::generate_service(t_service* tservice) { string f_service_i_name = get_out_dir() + capitalize(service_name_) + ".mli"; f_service_i_.open(f_service_i_name.c_str()); - f_service_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_service_i_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; + f_service_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_service_i_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; /* if (tservice->get_extends() != nullptr) { f_service_ << - "open " << capitalize(tservice->get_extends()->get_name()) << endl; + "open " << capitalize(tservice->get_extends()->get_name()) << '\n'; f_service_i_ << - "open " << capitalize(tservice->get_extends()->get_name()) << endl; + "open " << capitalize(tservice->get_extends()->get_name()) << '\n'; } */ - f_service_ << "open " << capitalize(program_name_) << "_types" << endl << endl; + f_service_ << "open " << capitalize(program_name_) << "_types" << '\n' << '\n'; - f_service_i_ << "open " << capitalize(program_name_) << "_types" << endl << endl; + f_service_i_ << "open " << capitalize(program_name_) << "_types" << '\n' << '\n'; // Generate the three main parts of the service generate_service_helpers(tservice); @@ -925,7 +923,7 @@ void t_ocaml_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - indent(f_service_) << "(* HELPER FUNCTIONS AND STRUCTURES *)" << endl << endl; + indent(f_service_) << "(* HELPER FUNCTIONS AND STRUCTURES *)" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -961,15 +959,15 @@ void t_ocaml_generator::generate_ocaml_function_helpers(t_function* tfunction) { * @param tservice The service to generate a header definition for */ void t_ocaml_generator::generate_service_interface(t_service* tservice) { - f_service_ << indent() << "class virtual iface =" << endl << "object (self)" << endl; - f_service_i_ << indent() << "class virtual iface :" << endl << "object" << endl; + f_service_ << indent() << "class virtual iface =" << '\n' << "object (self)" << '\n'; + f_service_i_ << indent() << "class virtual iface :" << '\n' << "object" << '\n'; indent_up(); if (tservice->get_extends() != nullptr) { string extends = type_name(tservice->get_extends()); - indent(f_service_) << "inherit " << extends << ".iface" << endl; - indent(f_service_i_) << "inherit " << extends << ".iface" << endl; + indent(f_service_) << "inherit " << extends << ".iface" << '\n'; + indent(f_service_i_) << "inherit " << extends << ".iface" << '\n'; } vector functions = tservice->get_functions(); @@ -977,13 +975,13 @@ void t_ocaml_generator::generate_service_interface(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string ft = function_type(*f_iter, true, true); f_service_ << indent() << "method virtual " << decapitalize((*f_iter)->get_name()) << " : " - << ft << endl; + << ft << '\n'; f_service_i_ << indent() << "method virtual " << decapitalize((*f_iter)->get_name()) << " : " - << ft << endl; + << ft << '\n'; } indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -995,17 +993,17 @@ void t_ocaml_generator::generate_service_interface(t_service* tservice) { */ void t_ocaml_generator::generate_service_client(t_service* tservice) { string extends = ""; - indent(f_service_) << "class client (iprot : Protocol.t) (oprot : Protocol.t) =" << endl - << "object (self)" << endl; - indent(f_service_i_) << "class client : Protocol.t -> Protocol.t -> " << endl << "object" << endl; + indent(f_service_) << "class client (iprot : Protocol.t) (oprot : Protocol.t) =" << '\n' + << "object (self)" << '\n'; + indent(f_service_i_) << "class client : Protocol.t -> Protocol.t -> " << '\n' << "object" << '\n'; indent_up(); if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends()); - indent(f_service_) << "inherit " << extends << ".client iprot oprot as super" << endl; - indent(f_service_i_) << "inherit " << extends << ".client" << endl; + indent(f_service_) << "inherit " << extends << ".client iprot oprot as super" << '\n'; + indent(f_service_i_) << "inherit " << extends << ".client" << '\n'; } - indent(f_service_) << "val mutable seqid = 0" << endl; + indent(f_service_) << "val mutable seqid = 0" << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1017,24 +1015,24 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << "method " << function_signature(*f_iter) << " = " << endl; + indent(f_service_) << "method " << function_signature(*f_iter) << " = " << '\n'; indent(f_service_i_) << "method " << decapitalize((*f_iter)->get_name()) << " : " - << function_type(*f_iter, true, false) << endl; + << function_type(*f_iter, true, false) << '\n'; indent_up(); indent(f_service_) << "self#send_" << funname; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << " " << decapitalize((*fld_iter)->get_name()); } - f_service_ << ";" << endl; + f_service_ << ";" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); - f_service_ << "self#recv_" << funname << endl; + f_service_ << "self#recv_" << funname << '\n'; } indent_down(); - indent(f_service_) << "method private send_" << function_signature(*f_iter) << " = " << endl; + indent(f_service_) << "method private send_" << function_signature(*f_iter) << " = " << '\n'; indent_up(); std::string argsname = decapitalize((*f_iter)->get_name() + "_args"); @@ -1042,19 +1040,19 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", " << ((*f_iter)->is_oneway() ? "Protocol.ONEWAY" : "Protocol.CALL") << ", seqid);" - << endl; + << '\n'; - f_service_ << indent() << "let args = new " << argsname << " in" << endl; + f_service_ << indent() << "let args = new " << argsname << " in" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args#set_" << (*fld_iter)->get_name() << " " - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } // Write to the stream - f_service_ << indent() << "args#write oprot;" << endl << indent() << "oprot#writeMessageEnd;" - << endl << indent() << "oprot#getTransport#flush" << endl; + f_service_ << indent() << "args#write oprot;" << '\n' << indent() << "oprot#writeMessageEnd;" + << '\n' << indent() << "oprot#getTransport#flush" << '\n'; indent_down(); indent_down(); @@ -1068,20 +1066,20 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { &noargs); // Open function f_service_ << indent() << "method private " << function_signature(&recv_function) << " =" - << endl; + << '\n'; indent_up(); // TODO(mcslee): Validate message reply here, seq ids etc. - f_service_ << indent() << "let (fname, mtype, rseqid) = iprot#readMessageBegin in" << endl; + f_service_ << indent() << "let (fname, mtype, rseqid) = iprot#readMessageBegin in" << '\n'; indent_up(); - f_service_ << indent() << "(if mtype = Protocol.EXCEPTION then" << endl << indent() - << " let x = Application_Exn.read iprot in" << endl; + f_service_ << indent() << "(if mtype = Protocol.EXCEPTION then" << '\n' << indent() + << " let x = Application_Exn.read iprot in" << '\n'; indent_up(); f_service_ << indent() << " (iprot#readMessageEnd;" << indent() - << " raise (Application_Exn.E x))" << endl; + << " raise (Application_Exn.E x))" << '\n'; indent_down(); - f_service_ << indent() << "else ());" << endl; + f_service_ << indent() << "else ());" << '\n'; string res = "_"; t_struct* xs = (*f_iter)->get_xceptions(); @@ -1090,32 +1088,32 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { if (!(*f_iter)->get_returntype()->is_void() || xceptions.size() > 0) { res = "result"; } - f_service_ << indent() << "let " << res << " = read_" << resultname << " iprot in" << endl; + f_service_ << indent() << "let " << res << " = read_" << resultname << " iprot in" << '\n'; indent_up(); - f_service_ << indent() << "iprot#readMessageEnd;" << endl; + f_service_ << indent() << "iprot#readMessageEnd;" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "match result#get_success with Some v -> v | None -> (" << endl; + f_service_ << indent() << "match result#get_success with Some v -> v | None -> (" << '\n'; indent_up(); } vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "(match result#get_" << (*x_iter)->get_name() - << " with None -> () | Some _v ->" << endl; + << " with None -> () | Some _v ->" << '\n'; indent(f_service_) << " raise (" << capitalize(exception_ctor((*x_iter)->get_type())) - << " _v));" << endl; + << " _v));" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "()" << endl; + indent(f_service_) << "()" << '\n'; } else { f_service_ << indent() << "raise (Application_Exn.E (Application_Exn.create Application_Exn.MISSING_RESULT \"" - << (*f_iter)->get_name() << " failed: unknown result\")))" << endl; + << (*f_iter)->get_name() << " failed: unknown result\")))" << '\n'; indent_down(); } @@ -1127,8 +1125,8 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { } indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -1142,50 +1140,50 @@ void t_ocaml_generator::generate_service_server(t_service* tservice) { vector::iterator f_iter; // Generate the header portion - indent(f_service_) << "class processor (handler : iface) =" << endl << indent() << "object (self)" - << endl; - indent(f_service_i_) << "class processor : iface ->" << endl << indent() << "object" << endl; + indent(f_service_) << "class processor (handler : iface) =" << '\n' << indent() << "object (self)" + << '\n'; + indent(f_service_i_) << "class processor : iface ->" << '\n' << indent() << "object" << '\n'; indent_up(); - f_service_ << indent() << "inherit Processor.t" << endl << endl; - f_service_i_ << indent() << "inherit Processor.t" << endl << endl; + f_service_ << indent() << "inherit Processor.t" << '\n' << '\n'; + f_service_i_ << indent() << "inherit Processor.t" << '\n' << '\n'; string extends = ""; if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends()); indent(f_service_) << "inherit " + extends + ".processor (handler :> " + extends + ".iface)" - << endl; - indent(f_service_i_) << "inherit " + extends + ".processor" << endl; + << '\n'; + indent(f_service_i_) << "inherit " + extends + ".processor" << '\n'; } if (extends.empty()) { - indent(f_service_) << "val processMap = Hashtbl.create " << functions.size() << endl; + indent(f_service_) << "val processMap = Hashtbl.create " << functions.size() << '\n'; } indent(f_service_i_) - << "val processMap : (string, int * Protocol.t * Protocol.t -> unit) Hashtbl.t" << endl; + << "val processMap : (string, int * Protocol.t * Protocol.t -> unit) Hashtbl.t" << '\n'; // Generate the server implementation - indent(f_service_) << "method process iprot oprot =" << endl; - indent(f_service_i_) << "method process : Protocol.t -> Protocol.t -> bool" << endl; + indent(f_service_) << "method process iprot oprot =" << '\n'; + indent(f_service_i_) << "method process : Protocol.t -> Protocol.t -> bool" << '\n'; indent_up(); - f_service_ << indent() << "let (name, typ, seqid) = iprot#readMessageBegin in" << endl; + f_service_ << indent() << "let (name, typ, seqid) = iprot#readMessageBegin in" << '\n'; indent_up(); // TODO(mcslee): validate message // HOT: dictionary function lookup - f_service_ << indent() << "if Hashtbl.mem processMap name then" << endl << indent() - << " (Hashtbl.find processMap name) (seqid, iprot, oprot)" << endl << indent() - << "else (" << endl << indent() << " iprot#skip(Protocol.T_STRUCT);" << endl - << indent() << " iprot#readMessageEnd;" << endl << indent() + f_service_ << indent() << "if Hashtbl.mem processMap name then" << '\n' << indent() + << " (Hashtbl.find processMap name) (seqid, iprot, oprot)" << '\n' << indent() + << "else (" << '\n' << indent() << " iprot#skip(Protocol.T_STRUCT);" << '\n' + << indent() << " iprot#readMessageEnd;" << '\n' << indent() << " let x = Application_Exn.create Application_Exn.UNKNOWN_METHOD (\"Unknown " - "function \"^name) in" << endl << indent() - << " oprot#writeMessageBegin(name, Protocol.EXCEPTION, seqid);" << endl << indent() - << " x#write oprot;" << endl << indent() << " oprot#writeMessageEnd;" << endl - << indent() << " oprot#getTransport#flush" << endl << indent() << ");" << endl; + "function \"^name) in" << '\n' << indent() + << " oprot#writeMessageBegin(name, Protocol.EXCEPTION, seqid);" << '\n' << indent() + << " x#write oprot;" << '\n' << indent() << " oprot#writeMessageEnd;" << '\n' + << indent() << " oprot#getTransport#flush" << '\n' << indent() << ");" << '\n'; // Read end of args field, the T_STOP, and the struct close - f_service_ << indent() << "true" << endl; + f_service_ << indent() << "true" << '\n'; indent_down(); indent_down(); // Generate the process subfunctions @@ -1193,17 +1191,17 @@ void t_ocaml_generator::generate_service_server(t_service* tservice) { generate_process_function(tservice, *f_iter); } - indent(f_service_) << "initializer" << endl; + indent(f_service_) << "initializer" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "Hashtbl.add processMap \"" << (*f_iter)->get_name() - << "\" self#process_" << (*f_iter)->get_name() << ";" << endl; + << "\" self#process_" << (*f_iter)->get_name() << ";" << '\n'; } indent_down(); indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -1215,7 +1213,7 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio (void)tservice; // Open function indent(f_service_) << "method private process_" << tfunction->get_name() - << " (seqid, iprot, oprot) =" << endl; + << " (seqid, iprot, oprot) =" << '\n'; indent_up(); string argsname = decapitalize(tfunction->get_name()) + "_args"; @@ -1231,9 +1229,9 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio args = "_"; } - f_service_ << indent() << "let " << args << " = read_" << argsname << " iprot in" << endl; + f_service_ << indent() << "let " << args << " = read_" << argsname << " iprot in" << '\n'; indent_up(); - f_service_ << indent() << "iprot#readMessageEnd;" << endl; + f_service_ << indent() << "iprot#readMessageEnd;" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1241,13 +1239,13 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "let result = new " << resultname << " in" << endl; + f_service_ << indent() << "let result = new " << resultname << " in" << '\n'; indent_up(); } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "(try" << endl; + f_service_ << indent() << "(try" << '\n'; indent_up(); } @@ -1259,20 +1257,20 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { f_service_ << " args#get_" << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (xceptions.size() > 0) { indent_down(); - indent(f_service_) << "with" << endl; + indent(f_service_) << "with" << '\n'; indent_up(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "| " << capitalize(exception_ctor((*x_iter)->get_type())) << " " - << (*x_iter)->get_name() << " -> " << endl; + << (*x_iter)->get_name() << " -> " << '\n'; indent_up(); indent_up(); if (!tfunction->is_oneway()) { f_service_ << indent() << "result#set_" << (*x_iter)->get_name() << " " - << (*x_iter)->get_name() << endl; + << (*x_iter)->get_name() << '\n'; } else { indent(f_service_) << "()"; } @@ -1280,21 +1278,21 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio indent_down(); } indent_down(); - f_service_ << indent() << ");" << endl; + f_service_ << indent() << ");" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "()" << endl; + f_service_ << indent() << "()" << '\n'; indent_down(); indent_down(); return; } f_service_ << indent() << "oprot#writeMessageBegin (\"" << tfunction->get_name() - << "\", Protocol.REPLY, seqid);" << endl << indent() << "result#write oprot;" << endl - << indent() << "oprot#writeMessageEnd;" << endl << indent() - << "oprot#getTransport#flush" << endl; + << "\", Protocol.REPLY, seqid);" << '\n' << indent() << "result#write oprot;" << '\n' + << indent() << "oprot#writeMessageEnd;" << '\n' << indent() + << "oprot#getTransport#flush" << '\n'; // Close function indent_down(); @@ -1311,7 +1309,7 @@ void t_ocaml_generator::generate_deserialize_field(ostream& out, t_field* tfield string name = decapitalize(tfield->get_name()); indent(out) << prefix << "#set_" << name << " "; generate_deserialize_type(out, type); - out << endl; + out << '\n'; } /** @@ -1396,46 +1394,46 @@ void t_ocaml_generator::generate_deserialize_container(ostream& out, t_type* tty t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << endl; + out << '\n'; indent_up(); // Declare variables, read header if (ttype->is_map()) { indent(out) << "(let (" << ktype << "," << vtype << "," << size << ") = iprot#readMapBegin in" - << endl; - indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << endl; + << '\n'; + indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << '\n'; indent_up(); - indent(out) << "for i = 1 to " << size << " do" << endl; + indent(out) << "for i = 1 to " << size << " do" << '\n'; indent_up(); indent(out) << "let _k = "; generate_deserialize_type(out, ((t_map*)ttype)->get_key_type()); - out << " in" << endl; + out << " in" << '\n'; indent(out) << "let _v = "; generate_deserialize_type(out, ((t_map*)ttype)->get_val_type()); - out << " in" << endl; + out << " in" << '\n'; indent_up(); - indent(out) << "Hashtbl.add " << con << " _k _v" << endl; + indent(out) << "Hashtbl.add " << con << " _k _v" << '\n'; indent_down(); indent_down(); indent(out) << "done; iprot#readMapEnd; " << con << ")"; indent_down(); } else if (ttype->is_set()) { - indent(out) << "(let (" << etype << "," << size << ") = iprot#readSetBegin in" << endl; - indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << endl; + indent(out) << "(let (" << etype << "," << size << ") = iprot#readSetBegin in" << '\n'; + indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << '\n'; indent_up(); - indent(out) << "for i = 1 to " << size << " do" << endl; + indent(out) << "for i = 1 to " << size << " do" << '\n'; indent_up(); indent(out) << "Hashtbl.add " << con << " "; generate_deserialize_type(out, ((t_set*)ttype)->get_elem_type()); - out << " true" << endl; + out << " true" << '\n'; indent_down(); indent(out) << "done; iprot#readSetEnd; " << con << ")"; indent_down(); } else if (ttype->is_list()) { - indent(out) << "(let (" << etype << "," << size << ") = iprot#readListBegin in" << endl; + indent(out) << "(let (" << etype << "," << size << ") = iprot#readListBegin in" << '\n'; indent_up(); indent(out) << "let " << con << " = (Array.to_list (Array.init " << size << " (fun _ -> "; generate_deserialize_type(out, ((t_list*)ttype)->get_elem_type()); - out << "))) in" << endl; + out << "))) in" << '\n'; indent_up(); indent(out) << "iprot#readListEnd; " << con << ")"; indent_down(); @@ -1510,7 +1508,7 @@ void t_ocaml_generator::generate_serialize_field(ostream& out, t_field* tfield, tfield->get_name().c_str(), type->get_name().c_str()); } - out << ";" << endl; + out << ";" << '\n'; } /** @@ -1528,38 +1526,38 @@ void t_ocaml_generator::generate_serialize_container(ostream& out, t_type* ttype if (ttype->is_map()) { indent(out) << "oprot#writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ","; out << type_to_enum(((t_map*)ttype)->get_val_type()) << ","; - out << "Hashtbl.length " << prefix << ");" << endl; + out << "Hashtbl.length " << prefix << ");" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot#writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ","; - out << "Hashtbl.length " << prefix << ");" << endl; + out << "Hashtbl.length " << prefix << ");" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot#writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ","; - out << "List.length " << prefix << ");" << endl; + out << "List.length " << prefix << ");" << '\n'; } if (ttype->is_map()) { string kiter = tmp("_kiter"); string viter = tmp("_viter"); - indent(out) << "Hashtbl.iter (fun " << kiter << " -> fun " << viter << " -> " << endl; + indent(out) << "Hashtbl.iter (fun " << kiter << " -> fun " << viter << " -> " << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } else if (ttype->is_set()) { string iter = tmp("_iter"); indent(out) << "Hashtbl.iter (fun " << iter << " -> fun _ -> "; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } else if (ttype->is_list()) { string iter = tmp("_iter"); indent(out) << "List.iter (fun " << iter << " -> "; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } if (ttype->is_map()) { diff --git a/compiler/cpp/src/thrift/generate/t_oop_generator.h b/compiler/cpp/src/thrift/generate/t_oop_generator.h index 88419620333..07b621639f7 100644 --- a/compiler/cpp/src/thrift/generate/t_oop_generator.h +++ b/compiler/cpp/src/thrift/generate/t_oop_generator.h @@ -42,13 +42,13 @@ class t_oop_generator : public t_generator { */ void scope_up(std::ostream& out) { - indent(out) << "{" << std::endl; + indent(out) << "{" << '\n'; indent_up(); } void scope_down(std::ostream& out) { indent_down(); - indent(out) << "}" << std::endl; + indent(out) << "}" << '\n'; } std::string upcase_string(std::string original) { diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc index d133b2455b5..8e533ca2903 100644 --- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * PERL code generator. * @@ -246,8 +244,8 @@ void t_perl_generator::init_generator() { f_types_ << autogen_comment() << perl_includes(); // Print header - f_consts_ << autogen_comment() << "package " << perl_namespace(program_) << "Constants;" << endl - << perl_includes() << endl; + f_consts_ << autogen_comment() << "package " << perl_namespace(program_) << "Constants;" << '\n' + << perl_includes() << '\n'; } /** @@ -271,10 +269,10 @@ string t_perl_generator::perl_includes() { */ void t_perl_generator::close_generator() { // Close types file - f_types_ << "1;" << endl; + f_types_ << "1;" << '\n'; f_types_.close(); - f_consts_ << "1;" << endl; + f_consts_ << "1;" << '\n'; f_consts_.close(); } @@ -294,13 +292,13 @@ void t_perl_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_perl_generator::generate_enum(t_enum* tenum) { - f_types_ << "package " << perl_namespace(program_) << tenum->get_name() << ";" << endl; + f_types_ << "package " << perl_namespace(program_) << tenum->get_name() << ";" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - f_types_ << "use constant " << (*c_iter)->get_name() << " => " << value << ";" << endl; + f_types_ << "use constant " << (*c_iter)->get_name() << " => " << value << ";" << '\n'; } } @@ -314,7 +312,7 @@ void t_perl_generator::generate_const(t_const* tconst) { f_consts_ << "use constant " << name << " => "; f_consts_ << render_const_value(type, value); - f_consts_ << ";" << endl << endl; + f_consts_ << ";" << '\n' << '\n'; } /** @@ -355,7 +353,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_enum()) { out << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << perl_namespace(type->get_program()) << type->get_name() << "->new({" << endl; + out << perl_namespace(type->get_program()) << type->get_name() << "->new({" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -376,14 +374,14 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) out << " => "; out << render_const_value(field_type, v_iter->second); out << ","; - out << endl; + out << '\n'; } indent_down(); indent(out) << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); @@ -392,7 +390,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) indent(out) << render_const_value(ktype, v_iter->first); out << " => "; out << render_const_value(vtype, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "}"; @@ -403,7 +401,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) } else { etype = ((t_set*)type)->get_elem_type(); } - out << "[" << endl; + out << "[" << '\n'; indent_up(); const vector& val = value->get_list(); @@ -414,7 +412,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) if (type->is_set()) { out << " => 1"; } - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "]"; @@ -480,12 +478,12 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, out << ") );\n"; } - out << endl; + out << '\n'; // new() indent_up(); - out << "sub new {" << endl << indent() << "my $classname = shift;" << endl << indent() - << "my $self = {};" << endl << indent() << "my $vals = shift || {};" << endl; + out << "sub new {" << '\n' << indent() << "my $classname = shift;" << '\n' << indent() + << "my $self = {};" << '\n' << indent() << "my $vals = shift || {};" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string dval = "undef"; @@ -493,7 +491,7 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, if ((*m_iter)->get_value() != nullptr && !(t->is_struct() || t->is_xception())) { dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value()); } - out << indent() << "$self->{" << (*m_iter)->get_name() << "} = " << dval << ";" << endl; + out << indent() << "$self->{" << (*m_iter)->get_name() << "} = " << dval << ";" << '\n'; } // Generate constructor from array @@ -503,27 +501,27 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "$self->{" << (*m_iter)->get_name() - << "} = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << "} = " << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } - out << indent() << "if (UNIVERSAL::isa($vals,'HASH')) {" << endl; + out << indent() << "if (UNIVERSAL::isa($vals,'HASH')) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << indent() << "if (defined $vals->{" << (*m_iter)->get_name() << "}) {" << endl + out << indent() << "if (defined $vals->{" << (*m_iter)->get_name() << "}) {" << '\n' << indent() << " $self->{" << (*m_iter)->get_name() << "} = $vals->{" - << (*m_iter)->get_name() << "};" << endl << indent() << "}" << endl; + << (*m_iter)->get_name() << "};" << '\n' << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << indent() << "return bless ($self, $classname);" << endl; + out << indent() << "return bless ($self, $classname);" << '\n'; indent_down(); out << "}\n\n"; - out << "sub getName {" << endl << indent() << " return '" << tstruct->get_name() << "';" << endl - << indent() << "}" << endl << endl; + out << "sub getName {" << '\n' << indent() << " return '" << tstruct->get_name() << "';" << '\n' + << indent() << "}" << '\n' << '\n'; generate_perl_struct_reader(out, tstruct); generate_perl_struct_writer(out, tstruct); @@ -536,32 +534,32 @@ void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstru const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << "sub read {" << endl; + out << "sub read {" << '\n'; indent_up(); - out << indent() << "my ($self, $input) = @_;" << endl << indent() << "my $xfer = 0;" << endl - << indent() << "my $fname;" << endl << indent() << "my $ftype = 0;" << endl << indent() - << "my $fid = 0;" << endl; + out << indent() << "my ($self, $input) = @_;" << '\n' << indent() << "my $xfer = 0;" << '\n' + << indent() << "my $fname;" << '\n' << indent() << "my $ftype = 0;" << '\n' << indent() + << "my $fid = 0;" << '\n'; - indent(out) << "$xfer += $input->readStructBegin(\\$fname);" << endl; + indent(out) << "$xfer += $input->readStructBegin(\\$fname);" << '\n'; // Loop over reading in fields - indent(out) << "while (1)" << endl; + indent(out) << "while (1)" << '\n'; scope_up(out); - indent(out) << "$xfer += $input->readFieldBegin(\\$fname, \\$ftype, \\$fid);" << endl; + indent(out) << "$xfer += $input->readFieldBegin(\\$fname, \\$ftype, \\$fid);" << '\n'; // Check for field STOP marker and break - indent(out) << "if ($ftype == Thrift::TType::STOP) {" << endl; + indent(out) << "if ($ftype == Thrift::TType::STOP) {" << '\n'; indent_up(); - indent(out) << "last;" << endl; + indent(out) << "last;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "SWITCH: for($fid)" << endl; + indent(out) << "SWITCH: for($fid)" << '\n'; scope_up(out); @@ -569,34 +567,34 @@ void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstru for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/^" << (*f_iter)->get_key() << "$/ && do{"; - indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "self->"); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; - indent(out) << " $xfer += $input->skip($ftype);" << endl; + indent(out) << " $xfer += $input->skip($ftype);" << '\n'; - out << indent() << "}" << endl << indent() << "last; };" << endl; + out << indent() << "}" << '\n' << indent() << "last; };" << '\n'; } // In the default case we skip the field - indent(out) << " $xfer += $input->skip($ftype);" << endl; + indent(out) << " $xfer += $input->skip($ftype);" << '\n'; scope_down(out); - indent(out) << "$xfer += $input->readFieldEnd();" << endl; + indent(out) << "$xfer += $input->readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "$xfer += $input->readStructEnd();" << endl; + indent(out) << "$xfer += $input->readStructEnd();" << '\n'; - indent(out) << "return $xfer;" << endl; + indent(out) << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -607,38 +605,38 @@ void t_perl_generator::generate_perl_struct_writer(ostream& out, t_struct* tstru const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - out << "sub write {" << endl; + out << "sub write {" << '\n'; indent_up(); - indent(out) << "my ($self, $output) = @_;" << endl; - indent(out) << "my $xfer = 0;" << endl; + indent(out) << "my ($self, $output) = @_;" << '\n'; + indent(out) << "my $xfer = 0;" << '\n'; - indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << endl; + indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "if (defined $self->{" << (*f_iter)->get_name() << "}) {" << endl; + out << indent() << "if (defined $self->{" << (*f_iter)->get_name() << "}) {" << '\n'; indent_up(); indent(out) << "$xfer += $output->writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self->"); - indent(out) << "$xfer += $output->writeFieldEnd();" << endl; + indent(out) << "$xfer += $output->writeFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << indent() << "$xfer += $output->writeFieldStop();" << endl << indent() - << "$xfer += $output->writeStructEnd();" << endl; + out << indent() << "$xfer += $output->writeFieldStop();" << '\n' << indent() + << "$xfer += $output->writeStructEnd();" << '\n'; - out << indent() << "return $xfer;" << endl; + out << indent() << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -655,13 +653,13 @@ void t_perl_generator::generate_use_includes(std::ostream& os, bool& done, t_typ std::vector& currInc = current->get_includes(); std::vector::size_type numInc = currInc.size(); if (selfish) { - os << "use " << perl_namespace(current) << "Types;" << endl; + os << "use " << perl_namespace(current) << "Types;" << '\n'; } for (std::vector::size_type i = 0; i < numInc; ++i) { t_program* incProgram = currInc.at(i); - os << "use " << perl_namespace(incProgram) << "Types;" << endl; + os << "use " << perl_namespace(incProgram) << "Types;" << '\n'; } - os << endl; + os << '\n'; done = true; } } @@ -683,10 +681,10 @@ void t_perl_generator::generate_service(t_service* tservice) { t_service* extends_s = tservice->get_extends(); if (extends_s != nullptr) { f_service_ << "use " << perl_namespace(extends_s->get_program()) << extends_s->get_name() << ";" - << endl; + << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the three main parts of the service (well, two for now in PERL) generate_service_helpers(tservice); @@ -696,7 +694,7 @@ void t_perl_generator::generate_service(t_service* tservice) { generate_service_processor(tservice); // Close service file - f_service_ << "1;" << endl; + f_service_ << "1;" << '\n'; f_service_.close(); } @@ -721,59 +719,59 @@ void t_perl_generator::generate_service_processor(t_service* tservice) { indent_up(); // Generate the header portion - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Processor;" << endl - << endl << "use strict;" << endl << extends_processor << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Processor;" << '\n' + << '\n' << "use strict;" << '\n' << extends_processor << '\n' << '\n'; if (extends.empty()) { - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $handler) = @_;" << endl << indent() - << "my $self = {};" << endl; + f_service_ << indent() << "my ($classname, $handler) = @_;" << '\n' << indent() + << "my $self = {};" << '\n'; - f_service_ << indent() << "$self->{handler} = $handler;" << endl; + f_service_ << indent() << "$self->{handler} = $handler;" << '\n'; - f_service_ << indent() << "return bless ($self, $classname);" << endl; + f_service_ << indent() << "return bless ($self, $classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } // Generate the server implementation - f_service_ << "sub process {" << endl; + f_service_ << "sub process {" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $input, $output) = @_;" << endl; + f_service_ << indent() << "my ($self, $input, $output) = @_;" << '\n'; - f_service_ << indent() << "my $rseqid = 0;" << endl << indent() << "my $fname = undef;" << endl - << indent() << "my $mtype = 0;" << endl << endl; + f_service_ << indent() << "my $rseqid = 0;" << '\n' << indent() << "my $fname = undef;" << '\n' + << indent() << "my $mtype = 0;" << '\n' << '\n'; - f_service_ << indent() << "$input->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" << endl; + f_service_ << indent() << "$input->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" << '\n'; // HOT: check for method implementation - f_service_ << indent() << "my $methodname = 'process_'.$fname;" << endl << indent() - << "if (!$self->can($methodname)) {" << endl; + f_service_ << indent() << "my $methodname = 'process_'.$fname;" << '\n' << indent() + << "if (!$self->can($methodname)) {" << '\n'; indent_up(); - f_service_ << indent() << "$input->skip(Thrift::TType::STRUCT);" << endl << indent() - << "$input->readMessageEnd();" << endl << indent() + f_service_ << indent() << "$input->skip(Thrift::TType::STRUCT);" << '\n' << indent() + << "$input->readMessageEnd();" << '\n' << indent() << "my $x = Thrift::TApplicationException->new('Function '.$fname.' not implemented.', " - "Thrift::TApplicationException::UNKNOWN_METHOD);" << endl << indent() - << "$output->writeMessageBegin($fname, Thrift::TMessageType::EXCEPTION, $rseqid);" << endl - << indent() << "$x->write($output);" << endl << indent() - << "$output->writeMessageEnd();" << endl << indent() - << "$output->getTransport()->flush();" << endl << indent() << "return;" << endl; + "Thrift::TApplicationException::UNKNOWN_METHOD);" << '\n' << indent() + << "$output->writeMessageBegin($fname, Thrift::TMessageType::EXCEPTION, $rseqid);" << '\n' + << indent() << "$x->write($output);" << '\n' << indent() + << "$output->writeMessageEnd();" << '\n' << indent() + << "$output->getTransport()->flush();" << '\n' << indent() << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl << indent() - << "$self->$methodname($rseqid, $input, $output);" << endl << indent() << "return 1;" - << endl; + f_service_ << indent() << "}" << '\n' << indent() + << "$self->$methodname($rseqid, $input, $output);" << '\n' << indent() << "return 1;" + << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -788,21 +786,21 @@ void t_perl_generator::generate_service_processor(t_service* tservice) { */ void t_perl_generator::generate_process_function(t_service* tservice, t_function* tfunction) { // Open function - f_service_ << "sub process_" << tfunction->get_name() << " {" << endl; + f_service_ << "sub process_" << tfunction->get_name() << " {" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $seqid, $input, $output) = @_;" << endl; + f_service_ << indent() << "my ($self, $seqid, $input, $output) = @_;" << '\n'; string argsname = perl_namespace(tservice->get_program()) + service_name_ + "_" + tfunction->get_name() + "_args"; string resultname = perl_namespace(tservice->get_program()) + service_name_ + "_" + tfunction->get_name() + "_result"; - f_service_ << indent() << "my $args = " << argsname << "->new();" << endl << indent() - << "$args->read($input);" << endl; + f_service_ << indent() << "my $args = " << argsname << "->new();" << '\n' << indent() + << "$args->read($input);" << '\n'; - f_service_ << indent() << "$input->readMessageEnd();" << endl; + f_service_ << indent() << "$input->readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -810,12 +808,12 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "my $result = " << resultname << "->new();" << endl; + f_service_ << indent() << "my $result = " << resultname << "->new();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "eval {" << endl; + f_service_ << indent() << "eval {" << '\n'; indent_up(); } @@ -838,55 +836,55 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "$args->" << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { indent_down(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "}; if( UNIVERSAL::isa($@,'" << perl_namespace((*x_iter)->get_type()->get_program()) - << (*x_iter)->get_type()->get_name() << "') ){ " << endl; + << (*x_iter)->get_type()->get_name() << "') ){ " << '\n'; indent_up(); - f_service_ << indent() << "$result->{" << (*x_iter)->get_name() << "} = $@;" << endl; - f_service_ << indent() << "$@ = undef;" << endl; + f_service_ << indent() << "$result->{" << (*x_iter)->get_name() << "} = $@;" << '\n'; + f_service_ << indent() << "$@ = undef;" << '\n'; indent_down(); f_service_ << indent(); } - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; // catch-all for unexpected exceptions (THRIFT-3191) - f_service_ << indent() << "if ($@) {" << endl; + f_service_ << indent() << "if ($@) {" << '\n'; indent_up(); - f_service_ << indent() << "$@ =~ s/^\\s+|\\s+$//g;" << endl - << indent() << "my $err = Thrift::TApplicationException->new(\"Unexpected Exception: \" . $@, Thrift::TApplicationException::INTERNAL_ERROR);" << endl - << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::EXCEPTION, $seqid);" << endl - << indent() << "$err->write($output);" << endl - << indent() << "$output->writeMessageEnd();" << endl - << indent() << "$output->getTransport()->flush();" << endl - << indent() << "$@ = undef;" << endl - << indent() << "return;" << endl; + f_service_ << indent() << "$@ =~ s/^\\s+|\\s+$//g;" << '\n' + << indent() << "my $err = Thrift::TApplicationException->new(\"Unexpected Exception: \" . $@, Thrift::TApplicationException::INTERNAL_ERROR);" << '\n' + << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::EXCEPTION, $seqid);" << '\n' + << indent() << "$err->write($output);" << '\n' + << indent() << "$output->writeMessageEnd();" << '\n' + << indent() << "$output->getTransport()->flush();" << '\n' + << indent() << "$@ = undef;" << '\n' + << indent() << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; return; } // Serialize the reply - f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::REPLY, $seqid);" << endl - << indent() << "$result->write($output);" << endl - << indent() << "$output->writeMessageEnd();" << endl - << indent() << "$output->getTransport()->flush();" << endl; + f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::REPLY, $seqid);" << '\n' + << indent() << "$result->write($output);" << '\n' + << indent() << "$output->writeMessageEnd();" << '\n' + << indent() << "$output->getTransport()->flush();" << '\n'; // Close function indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } /** @@ -898,7 +896,7 @@ void t_perl_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_ << "# HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -945,15 +943,15 @@ void t_perl_generator::generate_service_interface(t_service* tservice) { + "If);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "If;" << endl << endl - << "use strict;" << endl << extends_if << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "If;" << '\n' << '\n' + << "use strict;" << '\n' << extends_if << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << "sub " << function_signature(*f_iter) << endl << " die 'implement interface';\n}" - << endl << endl; + f_service_ << "sub " << function_signature(*f_iter) << '\n' << " die 'implement interface';\n}" + << '\n' << '\n'; } indent_down(); } @@ -970,31 +968,31 @@ void t_perl_generator::generate_service_rest(t_service* tservice) { extends_if = "use base qw(" + perl_namespace(extends_s->get_program()) + extends_s->get_name() + "Rest);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Rest;" << endl << endl - << "use strict;" << endl << extends_if << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Rest;" << '\n' << '\n' + << "use strict;" << '\n' << extends_if << '\n' << '\n'; if (extends.empty()) { - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $impl) = @_;" << endl << indent() - << "my $self ={ impl => $impl };" << endl << endl << indent() - << "return bless($self,$classname);" << endl; + f_service_ << indent() << "my ($classname, $impl) = @_;" << '\n' << indent() + << "my $self ={ impl => $impl };" << '\n' << '\n' << indent() + << "return bless($self,$classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << "sub " << (*f_iter)->get_name() << "{" << endl; + f_service_ << "sub " << (*f_iter)->get_name() << "{" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $request) = @_;" << endl << endl; + f_service_ << indent() << "my ($self, $request) = @_;" << '\n' << '\n'; const vector& args = (*f_iter)->get_arglist()->get_members(); vector::const_iterator a_iter; @@ -1002,19 +1000,19 @@ void t_perl_generator::generate_service_rest(t_service* tservice) { //t_type* atype = get_true_type((*a_iter)->get_type()); string req = "$request->{'" + (*a_iter)->get_name() + "'}"; f_service_ << indent() << "my $" << (*a_iter)->get_name() << " = (" << req << ") ? " << req - << " : undef;" << endl; + << " : undef;" << '\n'; /* slist no longer supported if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) { f_service_ << indent() << "my @" << (*a_iter)->get_name() << " = split(/,/, $" - << (*a_iter)->get_name() << ");" << endl << indent() << "$" - << (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << endl; + << (*a_iter)->get_name() << ");" << '\n' << indent() << "$" + << (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << '\n'; } */ } f_service_ << indent() << "return $self->{impl}->" << (*f_iter)->get_name() << "(" - << argument_list((*f_iter)->get_arglist()) << ");" << endl; + << argument_list((*f_iter)->get_arglist()) << ");" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } } @@ -1032,31 +1030,31 @@ void t_perl_generator::generate_service_client(t_service* tservice) { extends_client = "use base qw(" + extends + "Client);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Client;" << endl << endl - << extends_client << endl << "use base qw(" << perl_namespace(program_) - << service_name_ << "If);" << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Client;" << '\n' << '\n' + << extends_client << '\n' << "use base qw(" << perl_namespace(program_) + << service_name_ << "If);" << '\n'; // Constructor function - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $input, $output) = @_;" << endl << indent() - << "my $self = {};" << endl; + f_service_ << indent() << "my ($classname, $input, $output) = @_;" << '\n' << indent() + << "my $self = {};" << '\n'; if (!extends.empty()) { - f_service_ << indent() << "$self = $classname->SUPER::new($input, $output);" << endl; + f_service_ << indent() << "$self = $classname->SUPER::new($input, $output);" << '\n'; } else { - f_service_ << indent() << "$self->{input} = $input;" << endl << indent() - << "$self->{output} = defined $output ? $output : $input;" << endl << indent() - << "$self->{seqid} = 0;" << endl; + f_service_ << indent() << "$self->{input} = $input;" << '\n' << indent() + << "$self->{output} = defined $output ? $output : $input;" << '\n' << indent() + << "$self->{seqid} = 0;" << '\n'; } - f_service_ << indent() << "return bless($self,$classname);" << endl; + f_service_ << indent() << "return bless($self,$classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1068,7 +1066,7 @@ void t_perl_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - f_service_ << "sub " << function_signature(*f_iter) << endl; + f_service_ << "sub " << function_signature(*f_iter) << '\n'; indent_up(); @@ -1083,21 +1081,21 @@ void t_perl_generator::generate_service_client(t_service* tservice) { } f_service_ << "$" << (*fld_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "$self->recv_" << funname << "();" << endl; + f_service_ << "$self->recv_" << funname << "();" << '\n'; } indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; - f_service_ << "sub send_" << function_signature(*f_iter) << endl; + f_service_ << "sub send_" << function_signature(*f_iter) << '\n'; indent_up(); @@ -1107,23 +1105,23 @@ void t_perl_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', " << ((*f_iter)->is_oneway() ? "Thrift::TMessageType::ONEWAY" : "Thrift::TMessageType::CALL") - << ", $self->{seqid});" << endl; + << ", $self->{seqid});" << '\n'; - f_service_ << indent() << "my $args = " << argsname << "->new();" << endl; + f_service_ << indent() << "my $args = " << argsname << "->new();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "$args->{" << (*fld_iter)->get_name() << "} = $" - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } // Write to the stream - f_service_ << indent() << "$args->write($self->{output});" << endl << indent() - << "$self->{output}->writeMessageEnd();" << endl << indent() - << "$self->{output}->getTransport()->flush();" << endl; + f_service_ << indent() << "$args->write($self->{output});" << '\n' << indent() + << "$self->{output}->writeMessageEnd();" << '\n' << indent() + << "$self->{output}->getTransport()->flush();" << '\n'; indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; if (!(*f_iter)->is_oneway()) { std::string resultname = perl_namespace(tservice->get_program()) + service_name_ + "_" @@ -1134,29 +1132,29 @@ void t_perl_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_ << endl << "sub " << function_signature(&recv_function) << endl; + f_service_ << '\n' << "sub " << function_signature(&recv_function) << '\n'; indent_up(); - f_service_ << indent() << "my $rseqid = 0;" << endl << indent() << "my $fname;" << endl - << indent() << "my $mtype = 0;" << endl << endl; + f_service_ << indent() << "my $rseqid = 0;" << '\n' << indent() << "my $fname;" << '\n' + << indent() << "my $mtype = 0;" << '\n' << '\n'; f_service_ << indent() << "$self->{input}->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" - << endl << indent() << "if ($mtype == Thrift::TMessageType::EXCEPTION) {" << endl - << indent() << " my $x = Thrift::TApplicationException->new();" << endl << indent() - << " $x->read($self->{input});" << endl << indent() - << " $self->{input}->readMessageEnd();" << endl << indent() << " die $x;" << endl - << indent() << "}" << endl; + << '\n' << indent() << "if ($mtype == Thrift::TMessageType::EXCEPTION) {" << '\n' + << indent() << " my $x = Thrift::TApplicationException->new();" << '\n' << indent() + << " $x->read($self->{input});" << '\n' << indent() + << " $self->{input}->readMessageEnd();" << '\n' << indent() << " die $x;" << '\n' + << indent() << "}" << '\n'; - f_service_ << indent() << "my $result = " << resultname << "->new();" << endl << indent() - << "$result->read($self->{input});" << endl; + f_service_ << indent() << "my $result = " << resultname << "->new();" << '\n' << indent() + << "$result->read($self->{input});" << '\n'; - f_service_ << indent() << "$self->{input}->readMessageEnd();" << endl << endl; + f_service_ << indent() << "$self->{input}->readMessageEnd();" << '\n' << '\n'; // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (defined $result->{success} ) {" << endl << indent() - << " return $result->{success};" << endl << indent() << "}" << endl; + f_service_ << indent() << "if (defined $result->{success} ) {" << '\n' << indent() + << " return $result->{success};" << '\n' << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); @@ -1164,21 +1162,21 @@ void t_perl_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "if (defined $result->{" << (*x_iter)->get_name() << "}) {" - << endl << indent() << " die $result->{" << (*x_iter)->get_name() << "};" - << endl << indent() << "}" << endl; + << '\n' << indent() << " die $result->{" << (*x_iter)->get_name() << "};" + << '\n' << indent() << "}" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "die \"" << (*f_iter)->get_name() << " failed: unknown result\";" - << endl; + << '\n'; } // Close function indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; } } } @@ -1244,7 +1242,7 @@ void t_perl_generator::generate_deserialize_field(ostream& out, } else if (type->is_enum()) { out << "readI32(\\$" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -1263,8 +1261,8 @@ void t_perl_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << "$" << prefix << " = " << perl_namespace(tstruct->get_program()) - << tstruct->get_name() << "->new();" << endl << indent() << "$xfer += $" << prefix - << "->read($input);" << endl; + << tstruct->get_name() << "->new();" << '\n' << indent() << "$xfer += $" << prefix + << "->read($input);" << '\n'; } void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -1280,33 +1278,33 @@ void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttyp t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << indent() << "my $" << size << " = 0;" << endl; + out << indent() << "my $" << size << " = 0;" << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "$" << prefix << " = {};" << endl << indent() << "my $" << ktype << " = 0;" - << endl << indent() << "my $" << vtype << " = 0;" << endl; + out << indent() << "$" << prefix << " = {};" << '\n' << indent() << "my $" << ktype << " = 0;" + << '\n' << indent() << "my $" << vtype << " = 0;" << '\n'; out << indent() << "$xfer += $input->readMapBegin(" - << "\\$" << ktype << ", \\$" << vtype << ", \\$" << size << ");" << endl; + << "\\$" << ktype << ", \\$" << vtype << ", \\$" << size << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "$" << prefix << " = {};" << endl << indent() << "my $" << etype << " = 0;" - << endl << indent() << "$xfer += $input->readSetBegin(" - << "\\$" << etype << ", \\$" << size << ");" << endl; + out << indent() << "$" << prefix << " = {};" << '\n' << indent() << "my $" << etype << " = 0;" + << '\n' << indent() << "$xfer += $input->readSetBegin(" + << "\\$" << etype << ", \\$" << size << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "$" << prefix << " = [];" << endl << indent() << "my $" << etype << " = 0;" - << endl << indent() << "$xfer += $input->readListBegin(" - << "\\$" << etype << ", \\$" << size << ");" << endl; + out << indent() << "$" << prefix << " = [];" << '\n' << indent() << "my $" << etype << " = 0;" + << '\n' << indent() << "$xfer += $input->readListBegin(" + << "\\$" << etype << ", \\$" << size << ");" << '\n'; } // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (my $" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ")" - << endl; + << '\n'; scope_up(out); @@ -1322,11 +1320,11 @@ void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "$xfer += $input->readMapEnd();" << endl; + indent(out) << "$xfer += $input->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $input->readSetEnd();" << endl; + indent(out) << "$xfer += $input->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $input->readListEnd();" << endl; + indent(out) << "$xfer += $input->readListEnd();" << '\n'; } scope_down(out); @@ -1341,24 +1339,24 @@ void t_perl_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, true, true) << endl; - indent(out) << declare_field(&fval, true, true) << endl; + indent(out) << declare_field(&fkey, true, true) << '\n'; + indent(out) << declare_field(&fval, true, true) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << endl; + indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << '\n'; } void t_perl_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << "my $" << elem << " = undef;" << endl; + indent(out) << "my $" << elem << " = undef;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << endl; + indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << '\n'; } void t_perl_generator::generate_deserialize_list_element(ostream& out, @@ -1367,11 +1365,11 @@ void t_perl_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << "my $" << elem << " = undef;" << endl; + indent(out) << "my $" << elem << " = undef;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "push(@{$" << prefix << "},$" << elem << ");" << endl; + indent(out) << "push(@{$" << prefix << "},$" << elem << ");" << '\n'; } /** @@ -1435,7 +1433,7 @@ void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32($" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -1453,7 +1451,7 @@ void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_perl_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << "$xfer += $" << prefix << "->write($output);" << endl; + indent(out) << "$xfer += $" << prefix << "->write($output);" << '\n'; } /** @@ -1466,17 +1464,17 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, indent(out) << "$xfer += $output->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "scalar(keys %{$" << prefix << "}));" << endl; + << "scalar(keys %{$" << prefix << "}));" << '\n'; } else if (ttype->is_set()) { indent(out) << "$xfer += $output->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "scalar(@{$" << prefix << "}));" << endl; + << "scalar(@{$" << prefix << "}));" << '\n'; } else if (ttype->is_list()) { indent(out) << "$xfer += $output->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "scalar(@{$" << prefix << "}));" << endl; + << "scalar(@{$" << prefix << "}));" << '\n'; } scope_up(out); @@ -1485,7 +1483,7 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, string kiter = tmp("kiter"); string viter = tmp("viter"); indent(out) << "while( my ($" << kiter << ",$" << viter << ") = each %{$" << prefix << "}) " - << endl; + << '\n'; scope_up(out); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); @@ -1493,14 +1491,14 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "foreach my $" << iter << " (@{$" << prefix << "})" << endl; + indent(out) << "foreach my $" << iter << " (@{$" << prefix << "})" << '\n'; scope_up(out); generate_serialize_set_element(out, (t_set*)ttype, iter); scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "foreach my $" << iter << " (@{$" << prefix << "}) " << endl; + indent(out) << "foreach my $" << iter << " (@{$" << prefix << "}) " << '\n'; scope_up(out); generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); @@ -1509,11 +1507,11 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "$xfer += $output->writeMapEnd();" << endl; + indent(out) << "$xfer += $output->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $output->writeSetEnd();" << endl; + indent(out) << "$xfer += $output->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $output->writeListEnd();" << endl; + indent(out) << "$xfer += $output->writeListEnd();" << '\n'; } scope_down(out); diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc index 83738586821..6879501db0f 100644 --- a/compiler/cpp/src/thrift/generate/t_php_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc @@ -35,8 +35,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - #define NSGLOBAL (nsglobal_.size() ? nsglobal_ : "") #define NSGLOBAL_A ("\\" + NSGLOBAL) #define NSGLOBAL_B (NSGLOBAL + "\\") @@ -62,7 +60,7 @@ class t_php_generator : public t_oop_generator { validate_ = false; json_serializable_ = false; getters_setters_ = false; - + nsglobal_ = ""; // by default global namespace is empty classmap_ = false; for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { @@ -513,28 +511,28 @@ void t_php_generator::generate_typedef(t_typedef* ttypedef) { * Generates service header contains namespace suffix and includes inside file specified */ void t_php_generator::generate_service_header(t_service* tservice, std::ostream& file) { - file << "get_program()).empty()) { - file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl - << endl; + file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << '\n' + << '\n'; } file << autogen_comment() << php_includes(); - file << endl; + file << '\n'; } /** * Generates program header contains namespace suffix and includes inside file specified */ void t_php_generator::generate_program_header(std::ostream& file) { - file << "get_name() << endl - << "{" << endl; + f_enum << "final class " << tenum->get_name() << '\n' + << "{" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); generate_php_doc(f_enum, *c_iter); - indent(f_enum) << "const " << (*c_iter)->get_name() << " = " << value << ";" << endl - << endl; + indent(f_enum) << "const " << (*c_iter)->get_name() << " = " << value << ";" << '\n' + << '\n'; } - indent(f_enum) << "static public $__names = array(" << endl; + indent(f_enum) << "static public $__names = array(" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << value << " => '" << (*c_iter)->get_name() << "'," << endl; + indent(f_enum) << value << " => '" << (*c_iter)->get_name() << "'," << '\n'; } indent_down(); - indent(f_enum) << ");" << endl; + indent(f_enum) << ");" << '\n'; indent_down(); - f_enum << "}" << endl << endl; + f_enum << "}" << '\n' << '\n'; if (!classmap_) { f_enum.close(); } @@ -604,8 +602,8 @@ void t_php_generator::generate_consts(vector consts) { f_consts.open(f_consts_name.c_str()); generate_program_header(f_consts); } - f_consts << "final class Constant extends \\Thrift\\Type\\TConstant"<< endl - << "{" << endl; + f_consts << "final class Constant extends \\Thrift\\Type\\TConstant"<< '\n' + << "{" << '\n'; indent_up(); @@ -613,30 +611,30 @@ void t_php_generator::generate_consts(vector consts) { for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { string name = (*c_iter)->get_name(); - indent(f_consts) << "static protected $" << name << ";" << endl; + indent(f_consts) << "static protected $" << name << ";" << '\n'; } // Create init function for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { string name = (*c_iter)->get_name(); - f_consts << endl; + f_consts << '\n'; - f_consts << indent() << "protected static function init_" << name << "()" <get_type(), (*c_iter)->get_value()); - f_consts << ";" << endl; + f_consts << ";" << '\n'; indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; } indent_down(); - f_consts << "}" << endl; + f_consts << "}" << '\n'; if (!classmap_) { f_consts.close(); } @@ -679,7 +677,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_enum()) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl; + out << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -699,14 +697,14 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(g_type_string, v_iter->first); out << " => "; out << render_const_value(field_type, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "))"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "array(" << endl; + out << "array(" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; @@ -715,7 +713,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(ktype, v_iter->first); out << " => "; out << render_const_value(vtype, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << ")"; @@ -726,7 +724,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { } else { etype = ((t_set*)type)->get_elem_type(); } - out << "array(" << endl; + out << "array(" << '\n'; indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; @@ -736,7 +734,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { if (type->is_set()) { out << " => true"; } - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << ")"; @@ -779,27 +777,27 @@ void t_php_generator::generate_php_struct(t_struct* tstruct, bool is_exception) void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { t = get_true_type(t); - indent(out) << "'type' => " << type_to_enum(t) << "," << endl; + indent(out) << "'type' => " << type_to_enum(t) << "," << '\n'; if (t->is_base_type()) { // Noop, type is all we need } else if (t->is_struct() || t->is_xception() || t->is_enum()) { indent(out) << "'class' => '" << php_namespace(t->get_program()) << t->get_name() << "'," - << endl; + << '\n'; } else if (t->is_map()) { t_type* ktype = get_true_type(((t_map*)t)->get_key_type()); t_type* vtype = get_true_type(((t_map*)t)->get_val_type()); - indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << endl; - indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << endl; - indent(out) << "'key' => array(" << endl; + indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << '\n'; + indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << '\n'; + indent(out) << "'key' => array(" << '\n'; indent_up(); generate_php_type_spec(out, ktype); indent_down(); - indent(out) << ")," << endl; - indent(out) << "'val' => array(" << endl; + indent(out) << ")," << '\n'; + indent(out) << "'val' => array(" << '\n'; indent_up(); generate_php_type_spec(out, vtype); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; indent_down(); } else if (t->is_list() || t->is_set()) { t_type* etype; @@ -808,11 +806,11 @@ void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { } else { etype = get_true_type(((t_set*)t)->get_elem_type()); } - indent(out) << "'etype' => " << type_to_enum(etype) << "," << endl; - indent(out) << "'elem' => array(" << endl; + indent(out) << "'etype' => " << type_to_enum(etype) << "," << '\n'; + indent(out) << "'elem' => array(" << '\n'; indent_up(); generate_php_type_spec(out, etype); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; indent_down(); } else { throw "compiler error: no type for php struct spec field"; @@ -824,24 +822,24 @@ void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { * type information to generalize serialization routines. */ void t_php_generator::generate_php_struct_spec(ostream& out, t_struct* tstruct) { - indent(out) << "static public $_TSPEC = array(" << endl; + indent(out) << "static public $_TSPEC = array(" << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); - indent(out) << (*m_iter)->get_key() << " => array(" << endl; + indent(out) << (*m_iter)->get_key() << " => array(" << '\n'; indent_up(); - out << indent() << "'var' => '" << (*m_iter)->get_name() << "'," << endl; - out << indent() << "'isRequired' => " << ((*m_iter)->get_req() == t_field::T_REQUIRED ? "true" : "false") << "," << endl; + out << indent() << "'var' => '" << (*m_iter)->get_name() << "'," << '\n'; + out << indent() << "'isRequired' => " << ((*m_iter)->get_req() == t_field::T_REQUIRED ? "true" : "false") << "," << '\n'; generate_php_type_spec(out, t); indent_down(); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; } indent_down(); - indent(out) << ");" << endl << endl; + indent(out) << ");" << '\n' << '\n'; } /** * Generates necessary accessors and mutators for the fields @@ -865,10 +863,10 @@ void t_php_generator::generate_generic_field_getters_setters(std::ostream& out, indent_down(); } - indent(out) << endl; + indent(out) << '\n'; out << getter_stream.str(); out << setter_stream.str(); - indent(out) << endl; + indent(out) << '\n'; } /** * Generates a getter for the generated private fields @@ -878,16 +876,16 @@ void t_php_generator::generate_reflection_getters(ostringstream& out, string cap_name) { - out << indent() << "public function " << "get" << cap_name << "()" << endl - << indent() << "{" << endl; + out << indent() << "public function " << "get" << cap_name << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return $this->" << field_name << ";" << endl; + out << indent() << "return $this->" << field_name << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << endl; + out << indent() << "}" << '\n'; + out << '\n'; } /** * Generates a setter for the generated private fields @@ -896,17 +894,17 @@ void t_php_generator::generate_reflection_setters(ostringstream& out, string field_name, string cap_name) { - out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << endl - << indent() << "{" << endl; + out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "$this->" << field_name << " = $" << field_name << ";" << endl; + out << indent() << "$this->" << field_name << " = $" << field_name << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << endl; + out << indent() << "}" << '\n'; + out << '\n'; } /** * Gets the first-letter capitalized name for the field @@ -943,11 +941,11 @@ void t_php_generator::generate_php_struct_definition(ostream& out, if (json_serializable_) { out << " implements JsonSerializable"; } - out << endl - << "{" << endl; + out << '\n' + << "{" << '\n'; indent_up(); - out << indent() << "static public $isValidate = " << (validate_ ? "true" : "false") << ";" << endl << endl; + out << indent() << "static public $isValidate = " << (validate_ ? "true" : "false") << ";" << '\n' << '\n'; generate_php_struct_spec(out, tstruct); @@ -959,15 +957,15 @@ void t_php_generator::generate_php_struct_definition(ostream& out, } generate_php_doc(out, *m_iter); string access = (getters_setters_) ? "private" : "public"; - indent(out) << access << " $" << (*m_iter)->get_name() << " = " << dval << ";" << endl; + indent(out) << access << " $" << (*m_iter)->get_name() << " = " << dval << ";" << '\n'; } - out << endl; + out << '\n'; // Generate constructor from array string param = (members.size() > 0) ? "$vals = null" : ""; - out << indent() << "public function __construct(" << param << ")"<< endl - << indent() << "{" << endl; + out << indent() << "public function __construct(" << param << ")"<< '\n' + << indent() << "{" << '\n'; indent_up(); if (members.size() > 0) { @@ -975,62 +973,62 @@ void t_php_generator::generate_php_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "$this->" << (*m_iter)->get_name() << " = " - << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } - out << indent() << "if (is_array($vals)) {" << endl; + out << indent() << "if (is_array($vals)) {" << '\n'; indent_up(); if (oop_) { - out << indent() << "parent::__construct(self::$_TSPEC, $vals);" << endl; + out << indent() << "parent::__construct(self::$_TSPEC, $vals);" << '\n'; } else { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << endl; + out << indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << '\n'; indent_up(); out << indent() << "$this->" << (*m_iter)->get_name() << " = $vals['" - << (*m_iter)->get_name() << "'];" << endl; + << (*m_iter)->get_name() << "'];" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public function getName()" << endl - << indent() << "{" << endl; + out << indent() << "public function getName()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return '" << tstruct->get_name() << "';" << endl; + out << indent() << "return '" << tstruct->get_name() << "';" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << endl; + out << '\n'; if (getters_setters_) { generate_generic_field_getters_setters(out, tstruct); } generate_php_struct_reader(out, tstruct, is_result); - out << endl; + out << '\n'; generate_php_struct_writer(out, tstruct, is_result); if (needs_php_read_validator(tstruct, is_result)) { - out << endl; + out << '\n'; generate_php_struct_read_validator(out, tstruct); } if (needs_php_write_validator(tstruct, is_result)) { - out << endl; + out << '\n'; generate_php_struct_write_validator(out, tstruct); } if (json_serializable_) { - out << endl; + out << '\n'; generate_php_struct_json_serialize(out, tstruct, is_result); } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1040,34 +1038,34 @@ void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "public function read($input)" << endl; + indent(out) << "public function read($input)" << '\n'; scope_up(out); if (oop_) { if (needs_php_read_validator(tstruct, is_result)) { indent(out) << "$tmp = $this->_read('" << tstruct->get_name() << "', self::$_TSPEC, $input);" - << endl; - indent(out) << "$this->_validateForRead();" << endl; - indent(out) << "return $tmp;" << endl; + << '\n'; + indent(out) << "$this->_validateForRead();" << '\n'; + indent(out) << "return $tmp;" << '\n'; } else { indent(out) << "return $this->_read('" << tstruct->get_name() << "', self::$_TSPEC, $input);" - << endl; + << '\n'; } scope_down(out); - out << endl; + out << '\n'; return; } - out << indent() << "$xfer = 0;" << endl << indent() << "$fname = null;" << endl << indent() - << "$ftype = 0;" << endl << indent() << "$fid = 0;" << endl; + out << indent() << "$xfer = 0;" << '\n' << indent() << "$fname = null;" << '\n' << indent() + << "$ftype = 0;" << '\n' << indent() << "$fid = 0;" << '\n'; // Declare stack tmp variables if (!binary_inline_) { - indent(out) << "$xfer += $input->readStructBegin($fname);" << endl; + indent(out) << "$xfer += $input->readStructBegin($fname);" << '\n'; } // Loop over reading in fields - indent(out) << "while (true) {" << endl; + indent(out) << "while (true) {" << '\n'; indent_up(); @@ -1077,80 +1075,80 @@ void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct t_field ffid(g_type_i16, "fid"); generate_deserialize_field(out, &fftype); out << indent() << "if ($ftype == " - << "TType::STOP) {" << endl << indent() << " break;" << endl << indent() << "}" << endl; + << "TType::STOP) {" << '\n' << indent() << " break;" << '\n' << indent() << "}" << '\n'; generate_deserialize_field(out, &ffid); } else { - indent(out) << "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << endl; + indent(out) << "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << '\n'; // Check for field STOP marker and break indent(out) << "if ($ftype == " - << "TType::STOP) {" << endl; + << "TType::STOP) {" << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } // Switch statement on the field we are reading - indent(out) << "switch ($fid) {" << endl; + indent(out) << "switch ($fid) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << (*f_iter)->get_key() << ":" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this->"); indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); if (binary_inline_) { - indent(out) << "$xfer += TProtocol::skipBinary($input, $ftype);" << endl; + indent(out) << "$xfer += TProtocol::skipBinary($input, $ftype);" << '\n'; } else { - indent(out) << "$xfer += $input->skip($ftype);" << endl; + indent(out) << "$xfer += $input->skip($ftype);" << '\n'; } indent_down(); - out << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // In the default case we skip the field - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); if (binary_inline_) { indent(out) << "$xfer += " - << "TProtocol::skipBinary($input, $ftype);" << endl; + << "TProtocol::skipBinary($input, $ftype);" << '\n'; } else { - indent(out) << "$xfer += $input->skip($ftype);" << endl; + indent(out) << "$xfer += $input->skip($ftype);" << '\n'; } - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); scope_down(out); if (!binary_inline_) { // Read field end marker - indent(out) << "$xfer += $input->readFieldEnd();" << endl; + indent(out) << "$xfer += $input->readFieldEnd();" << '\n'; } scope_down(out); if (!binary_inline_) { - indent(out) << "$xfer += $input->readStructEnd();" << endl; + indent(out) << "$xfer += $input->readStructEnd();" << '\n'; } if (needs_php_read_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForRead();" << endl; + indent(out) << "$this->_validateForRead();" << '\n'; } - indent(out) << "return $xfer;" << endl; + indent(out) << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1162,33 +1160,33 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct vector::const_iterator f_iter; if (binary_inline_) { - indent(out) << "public function write(&$output)" << endl; + indent(out) << "public function write(&$output)" << '\n'; } else { - indent(out) << "public function write($output)" << endl; + indent(out) << "public function write($output)" << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); if (needs_php_write_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForWrite();" << endl; + indent(out) << "$this->_validateForWrite();" << '\n'; } if (oop_) { indent(out) << "return $this->_write('" << tstruct->get_name() << "', self::$_TSPEC, $output);" - << endl; + << '\n'; scope_down(out); - out << endl; + out << '\n'; return; } - indent(out) << "$xfer = 0;" << endl; + indent(out) << "$xfer = 0;" << '\n'; if (!binary_inline_) { - indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << endl; + indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << '\n'; } for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "if ($this->" << (*f_iter)->get_name() << " !== null) {" << endl; + out << indent() << "if ($this->" << (*f_iter)->get_name() << " !== null) {" << '\n'; indent_up(); t_type* type = get_true_type((*f_iter)->get_type()); @@ -1200,22 +1198,22 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct } if (!expect.empty()) { out << indent() << "if (!is_" << expect << "($this->" << (*f_iter)->get_name() << ")) {" - << endl; + << '\n'; indent_up(); out << indent() << "throw new " << "TProtocolException('Bad type in structure.', " - << "TProtocolException::INVALID_DATA);" << endl; + << "TProtocolException::INVALID_DATA);" << '\n'; scope_down(out); } // Write field header if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum((*f_iter)->get_type()) << ");" - << endl << indent() << "$output .= pack('n', " << (*f_iter)->get_key() << ");" << endl; + << '\n' << indent() << "$output .= pack('n', " << (*f_iter)->get_key() << ");" << '\n'; } else { indent(out) << "$xfer += $output->writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; } // Write field contents @@ -1223,25 +1221,25 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct // Write field closer if (!binary_inline_) { - indent(out) << "$xfer += $output->writeFieldEnd();" << endl; + indent(out) << "$xfer += $output->writeFieldEnd();" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (binary_inline_) { out << indent() << "$output .= pack('c', " - << "TType::STOP);" << endl; + << "TType::STOP);" << '\n'; } else { - out << indent() << "$xfer += $output->writeFieldStop();" << endl << indent() - << "$xfer += $output->writeStructEnd();" << endl; + out << indent() << "$xfer += $output->writeFieldStop();" << '\n' << indent() + << "$xfer += $output->writeStructEnd();" << '\n'; } - out << indent() << "return $xfer;" << endl; + out << indent() << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_php_generator::generate_php_struct_read_validator(ostream& out, t_struct* tstruct) { @@ -1256,7 +1254,7 @@ void t_php_generator::generate_php_struct_required_validator(ostream& out, t_struct* tstruct, std::string method_name, bool write_mode) { - indent(out) << "private function " << method_name << "() {" << endl; + indent(out) << "private function " << method_name << "() {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1268,32 +1266,32 @@ void t_php_generator::generate_php_struct_required_validator(ostream& out, t_field* field = (*f_iter); if (field->get_req() == t_field::T_REQUIRED || (field->get_req() == t_field::T_OPT_IN_REQ_OUT && write_mode)) { - indent(out) << "if ($this->" << field->get_name() << " === null) {" << endl; + indent(out) << "if ($this->" << field->get_name() << " === null) {" << '\n'; indent_up(); indent(out) << "throw new TProtocolException('Required field " << tstruct->get_name() << "." - << field->get_name() << " is unset!');" << endl; + << field->get_name() << " is unset!');" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_php_generator::generate_php_struct_json_serialize(ostream& out, t_struct* tstruct, bool is_result) { - indent(out) << "#[\\ReturnTypeWillChange]" << endl; - indent(out) << "public function jsonSerialize() {" << endl; + indent(out) << "#[\\ReturnTypeWillChange]" << '\n'; + indent(out) << "public function jsonSerialize() {" << '\n'; indent_up(); if (needs_php_write_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForWrite();" << endl; + indent(out) << "$this->_validateForWrite();" << '\n'; } - indent(out) << "$json = new stdClass;" << endl; + indent(out) << "$json = new stdClass;" << '\n'; const vector& fields = tstruct->get_members(); @@ -1312,7 +1310,7 @@ void t_php_generator::generate_php_struct_json_serialize(ostream& out, continue; } } - indent(out) << "if ($this->" << name << " !== null) {" << endl; + indent(out) << "if ($this->" << name << " !== null) {" << '\n'; indent_up(); indent(out) << "$json->" << name << " = "; if (type->is_map()) { @@ -1320,16 +1318,16 @@ void t_php_generator::generate_php_struct_json_serialize(ostream& out, } else { out << type_to_cast(type); } - out << "$this->" << name << ";" << endl; + out << "$this->" << name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } - indent(out) << "return $json;" << endl; + indent(out) << "return $json;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } int t_php_generator::get_php_num_required_fields(const vector& fields, bool write_mode) { @@ -1382,7 +1380,7 @@ void t_php_generator::generate_service(t_service* tservice) { if(classmap_) { // Close service file - f_service_ << endl; + f_service_ << '\n'; f_service_.close(); } } @@ -1413,34 +1411,34 @@ void t_php_generator::generate_service_processor(t_service* tservice) { } // Generate the header portion - f_service_processor << "class " << service_name_ << "Processor" << extends_processor << endl - << "{" << endl; + f_service_processor << "class " << service_name_ << "Processor" << extends_processor << '\n' + << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_processor << indent() << "protected $handler_ = null;" << endl; + f_service_processor << indent() << "protected $handler_ = null;" << '\n'; } - f_service_processor << indent() << "public function __construct($handler)"<< endl - << indent() << "{" << endl; + f_service_processor << indent() << "public function __construct($handler)"<< '\n' + << indent() << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_processor << indent() << "$this->handler_ = $handler;" << endl; + f_service_processor << indent() << "$this->handler_ = $handler;" << '\n'; } else { - f_service_processor << indent() << "parent::__construct($handler);" << endl; + f_service_processor << indent() << "parent::__construct($handler);" << '\n'; } indent_down(); - f_service_processor << indent() << "}" << endl << endl; + f_service_processor << indent() << "}" << '\n' << '\n'; // Generate the server implementation - f_service_processor << indent() << "public function process($input, $output)" << endl - << indent() << "{" << endl; + f_service_processor << indent() << "public function process($input, $output)" << '\n' + << indent() << "{" << '\n'; indent_up(); - f_service_processor << indent() << "$rseqid = 0;" << endl << indent() << "$fname = null;" << endl - << indent() << "$mtype = 0;" << endl << endl; + f_service_processor << indent() << "$rseqid = 0;" << '\n' << indent() << "$fname = null;" << '\n' + << indent() << "$mtype = 0;" << '\n' << '\n'; if (binary_inline_) { t_field ffname(g_type_string, "fname"); @@ -1450,36 +1448,36 @@ void t_php_generator::generate_service_processor(t_service* tservice) { generate_deserialize_field(f_service_processor, &fmtype, "", true); generate_deserialize_field(f_service_processor, &fseqid, "", true); } else { - f_service_processor << indent() << "$input->readMessageBegin($fname, $mtype, $rseqid);" << endl; + f_service_processor << indent() << "$input->readMessageBegin($fname, $mtype, $rseqid);" << '\n'; } // HOT: check for method implementation - f_service_processor << indent() << "$methodname = 'process_'.$fname;" << endl - << indent() << "if (!method_exists($this, $methodname)) {" << endl; + f_service_processor << indent() << "$methodname = 'process_'.$fname;" << '\n' + << indent() << "if (!method_exists($this, $methodname)) {" << '\n'; indent_up(); if (binary_inline_) { - f_service_processor << indent() << "throw new \\Exception('Function '.$fname.' not implemented.');" << endl; + f_service_processor << indent() << "throw new \\Exception('Function '.$fname.' not implemented.');" << '\n'; } else { f_service_processor << indent() << " $input->skip(" - << "TType::STRUCT);" << endl << indent() << " $input->readMessageEnd();" << endl + << "TType::STRUCT);" << '\n' << indent() << " $input->readMessageEnd();" << '\n' << indent() << " $x = new " << "TApplicationException('Function '.$fname.' not implemented.', " - << "TApplicationException::UNKNOWN_METHOD);" << endl << indent() + << "TApplicationException::UNKNOWN_METHOD);" << '\n' << indent() << " $output->writeMessageBegin($fname, " - << "TMessageType::EXCEPTION, $rseqid);" << endl << indent() - << " $x->write($output);" << endl << indent() << " $output->writeMessageEnd();" - << endl << indent() << " $output->getTransport()->flush();" << endl << indent() - << " return;" << endl; + << "TMessageType::EXCEPTION, $rseqid);" << '\n' << indent() + << " $x->write($output);" << '\n' << indent() << " $output->writeMessageEnd();" + << '\n' << indent() << " $output->getTransport()->flush();" << '\n' << indent() + << " return;" << '\n'; } indent_down(); - f_service_processor << indent() << "}" << endl - << indent() << "$this->$methodname($rseqid, $input, $output);" << endl - << indent() << "return true;" << endl; + f_service_processor << indent() << "}" << '\n' + << indent() << "$this->$methodname($rseqid, $input, $output);" << '\n' + << indent() << "return true;" << '\n'; indent_down(); - f_service_processor << indent() << "}" << endl << endl; + f_service_processor << indent() << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1487,7 +1485,7 @@ void t_php_generator::generate_service_processor(t_service* tservice) { } indent_down(); - f_service_processor << "}" << endl; + f_service_processor << "}" << '\n'; if (!classmap_) { f_service_processor.close(); @@ -1501,8 +1499,8 @@ void t_php_generator::generate_service_processor(t_service* tservice) { */ void t_php_generator::generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction) { // Open function - out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << endl - << indent() << "{" << endl; + out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << '\n' + << indent() << "{" << '\n'; indent_up(); string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" @@ -1512,32 +1510,32 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts out << indent() << "$bin_accel = ($input instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_read_binary_after_message_begin');" - << endl; - out << indent() << "if ($bin_accel) {" << endl; + << '\n'; + out << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - out << indent() << "$args = thrift_protocol_read_binary_after_message_begin(" <isStrictRead()" <isStrictRead()" << '\n'; indent_down(); - out << indent() <<");" << endl; + out << indent() <<");" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "$args = new " << argsname << "();" << endl - << indent() << "$args->read($input);" << endl; + out << indent() << "$args = new " << argsname << "();" << '\n' + << indent() << "$args->read($input);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (!binary_inline_) { - out << indent() << "$input->readMessageEnd();" << endl; + out << indent() << "$input->readMessageEnd();" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -1546,12 +1544,12 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts // Declare result for non oneway function if (!tfunction->is_oneway()) { - out << indent() << "$result = new " << resultname << "();" << endl; + out << indent() << "$result = new " << resultname << "();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); } @@ -1574,7 +1572,7 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts } out << "$args->" << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { indent_down(); @@ -1582,70 +1580,70 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts out << indent() << "} catch (" << php_namespace(get_true_type((*x_iter)->get_type())->get_program()) << (*x_iter)->get_type()->get_name() << " $" << (*x_iter)->get_name() << ") {" - << endl; + << '\n'; if (!tfunction->is_oneway()) { indent_up(); out << indent() << "$result->" << (*x_iter)->get_name() << " = $" - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); out << indent(); } } - out << "}" << endl; + out << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; return; } out << indent() << "$bin_accel = ($output instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_write_binary');" - << endl; + << '\n'; - out << indent() << "if ($bin_accel) {" << endl; + out << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - out << indent() << "thrift_protocol_write_binary(" << endl; + out << indent() << "thrift_protocol_write_binary(" << '\n'; indent_up(); - out << indent() << "$output,"<get_name()<< "'," <isStrictWrite()"<get_name()<< "'," << '\n' + << indent() << "TMessageType::REPLY,"<< '\n' + << indent() << "$result," << '\n' + << indent() << "$seqid," << '\n' + << indent() << "$output->isStrictWrite()"<< '\n'; indent_down(); - out << indent() << ");" << endl; + out << indent() << ");" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); // Serialize the request header if (binary_inline_) { out << indent() << "$buff = pack('N', (0x80010000 | " - << "TMessageType::REPLY)); " << endl << indent() << "$buff .= pack('N', strlen('" - << tfunction->get_name() << "'));" << endl << indent() << "$buff .= '" - << tfunction->get_name() << "';" << endl << indent() << "$buff .= pack('N', $seqid);" - << endl << indent() << "$result->write($buff);" << endl << indent() - << "$output->write($buff);" << endl << indent() << "$output->flush();" << endl; + << "TMessageType::REPLY)); " << '\n' << indent() << "$buff .= pack('N', strlen('" + << tfunction->get_name() << "'));" << '\n' << indent() << "$buff .= '" + << tfunction->get_name() << "';" << '\n' << indent() << "$buff .= pack('N', $seqid);" + << '\n' << indent() << "$result->write($buff);" << '\n' << indent() + << "$output->write($buff);" << '\n' << indent() << "$output->flush();" << '\n'; } else { out << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', " - << "TMessageType::REPLY, $seqid);" << endl << indent() << "$result->write($output);" - << endl << indent() << "$output->writeMessageEnd();" << endl << indent() - << "$output->getTransport()->flush();" << endl; + << "TMessageType::REPLY, $seqid);" << '\n' << indent() << "$result->write($output);" + << '\n' << indent() << "$output->writeMessageEnd();" << '\n' << indent() + << "$output->getTransport()->flush();" << '\n'; } scope_down(out); // Close function indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1659,7 +1657,7 @@ void t_php_generator::generate_service_helpers(t_service* tservice) { ofstream_with_content_based_conditional_update& f_struct_definition = f_service_; if (classmap_) { - f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1738,18 +1736,18 @@ void t_php_generator::generate_service_interface(t_service* tservice) { + tservice->get_extends()->get_name() + "If"; } generate_php_doc(f_service_interface, tservice); - f_service_interface << "interface " << php_namespace_declaration(tservice) << "If" << extends_if << endl - << "{" << endl; + f_service_interface << "interface " << php_namespace_declaration(tservice) << "If" << extends_if << '\n' + << "{" << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_php_doc(f_service_interface, *f_iter); - indent(f_service_interface) << "public function " << function_signature(*f_iter) << ";" << endl; + indent(f_service_interface) << "public function " << function_signature(*f_iter) << ";" << '\n'; } indent_down(); - f_service_interface << "}" << endl; + f_service_interface << "}" << '\n'; // Close service interface file if (!classmap_) { @@ -1776,21 +1774,21 @@ void t_php_generator::generate_service_rest(t_service* tservice) { extends_if = " extends " + php_namespace(tservice->get_extends()->get_program()) + tservice->get_extends()->get_name() + "Rest"; } - f_service_rest << "class " << service_name_ << "Rest" << extends_if << endl - << "{" << endl; + f_service_rest << "class " << service_name_ << "Rest" << extends_if << '\n' + << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_rest << indent() << "protected $impl_;" << endl << endl; + f_service_rest << indent() << "protected $impl_;" << '\n' << '\n'; } - f_service_rest << indent() << "public function __construct($impl) {" << endl << indent() - << " $this->impl_ = $impl;" << endl << indent() << "}" << endl << endl; + f_service_rest << indent() << "public function __construct($impl) {" << '\n' << indent() + << " $this->impl_ = $impl;" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - indent(f_service_rest) << "public function " << (*f_iter)->get_name() << "($request) {" << endl; + indent(f_service_rest) << "public function " << (*f_iter)->get_name() << "($request) {" << '\n'; indent_up(); const vector& args = (*f_iter)->get_arglist()->get_members(); vector::const_iterator a_iter; @@ -1800,39 +1798,39 @@ void t_php_generator::generate_service_rest(t_service* tservice) { string req = "$request['" + (*a_iter)->get_name() + "']"; if (atype->is_bool()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = " << cast << "(!empty(" << req - << ") && (" << req << " !== 'false'));" << endl; + << ") && (" << req << " !== 'false'));" << '\n'; } else { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " - << cast << req << " : null;" << endl; + << cast << req << " : null;" << '\n'; } /* slist no longer supported if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = explode(',', $" - << (*a_iter)->get_name() << ");" << endl; + << (*a_iter)->get_name() << ");" << '\n'; } else */ if (atype->is_map() || atype->is_list()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = json_decode($" - << (*a_iter)->get_name() << ", true);" << endl; + << (*a_iter)->get_name() << ", true);" << '\n'; } else if (atype->is_set()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = array_fill_keys(json_decode($" - << (*a_iter)->get_name() << ", true), 1);" << endl; + << (*a_iter)->get_name() << ", true), 1);" << '\n'; } else if (atype->is_struct() || atype->is_xception()) { - f_service_rest << indent() << "if ($" << (*a_iter)->get_name() << " !== null) {" << endl + f_service_rest << indent() << "if ($" << (*a_iter)->get_name() << " !== null) {" << '\n' << indent() << " $" << (*a_iter)->get_name() << " = new " << php_namespace(atype->get_program()) << atype->get_name() << "(json_decode($" - << (*a_iter)->get_name() << ", true));" << endl << indent() << "}" << endl; + << (*a_iter)->get_name() << ", true));" << '\n' << indent() << "}" << '\n'; } } f_service_rest << indent() << "return $this->impl_->" << (*f_iter)->get_name() << "(" - << argument_list((*f_iter)->get_arglist(), false) << ");" << endl; + << argument_list((*f_iter)->get_arglist(), false) << ");" << '\n'; indent_down(); - indent(f_service_rest) << "}" << endl << endl; + indent(f_service_rest) << "}" << '\n' << '\n'; } indent_down(); - f_service_rest << "}" << endl << endl; + f_service_rest << "}" << '\n' << '\n'; // Close service rest file - f_service_rest << endl; + f_service_rest << '\n'; if (!classmap_) { f_service_rest.close(); } @@ -1860,31 +1858,31 @@ void t_php_generator::generate_service_client(t_service* tservice) { } f_service_client << "class " << php_namespace_declaration(tservice) << "Client" << extends_client - << " implements " << php_namespace(tservice->get_program()) << service_name_ << "If" << endl - <<"{"<< endl; + << " implements " << php_namespace(tservice->get_program()) << service_name_ << "If" << '\n' + <<"{"<< '\n'; indent_up(); // Private members if (extends.empty()) { - f_service_client << indent() << "protected $input_ = null;" << endl << indent() - << "protected $output_ = null;" << endl << endl; - f_service_client << indent() << "protected $seqid_ = 0;" << endl << endl; + f_service_client << indent() << "protected $input_ = null;" << '\n' << indent() + << "protected $output_ = null;" << '\n' << '\n'; + f_service_client << indent() << "protected $seqid_ = 0;" << '\n' << '\n'; } // Constructor function - f_service_client << indent() << "public function __construct($input, $output = null)" << endl - << indent() << "{" << endl; + f_service_client << indent() << "public function __construct($input, $output = null)" << '\n' + << indent() << "{" << '\n'; indent_up(); if (!extends.empty()) { - f_service_client << indent() << "parent::__construct($input, $output);" << endl; + f_service_client << indent() << "parent::__construct($input, $output);" << '\n'; } else { - f_service_client << indent() << "$this->input_ = $input;" << endl - << indent() << "$this->output_ = $output ? $output : $input;" << endl; + f_service_client << indent() << "$this->input_ = $input;" << '\n' + << indent() << "$this->output_ = $output ? $output : $input;" << '\n'; } indent_down(); - f_service_client << indent() << "}" << endl << endl; + f_service_client << indent() << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1895,10 +1893,10 @@ void t_php_generator::generate_service_client(t_service* tservice) { vector::const_iterator fld_iter; string funname = (*f_iter)->get_name(); - f_service_client << endl; + f_service_client << '\n'; // Open function - indent(f_service_client) << "public function " << function_signature(*f_iter) << endl; + indent(f_service_client) << "public function " << function_signature(*f_iter) << '\n'; scope_up(f_service_client); indent(f_service_client) << "$this->send_" << funname << "("; @@ -1911,77 +1909,77 @@ void t_php_generator::generate_service_client(t_service* tservice) { } f_service_client << "$" << (*fld_iter)->get_name(); } - f_service_client << ");" << endl; + f_service_client << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_client << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_client << "return "; } - f_service_client << "$this->recv_" << funname << "();" << endl; + f_service_client << "$this->recv_" << funname << "();" << '\n'; } scope_down(f_service_client); - f_service_client << endl; + f_service_client << '\n'; - indent(f_service_client) << "public function send_" << function_signature(*f_iter) << endl; + indent(f_service_client) << "public function send_" << function_signature(*f_iter) << '\n'; scope_up(f_service_client); std::string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_args"; - f_service_client << indent() << "$args = new " << argsname << "();" << endl; + f_service_client << indent() << "$args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_client << indent() << "$args->" << (*fld_iter)->get_name() << " = $" - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } f_service_client << indent() << "$bin_accel = ($this->output_ instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_write_binary');" - << endl; + << '\n'; - f_service_client << indent() << "if ($bin_accel) {" << endl; + f_service_client << indent() << "if ($bin_accel) {" << '\n'; indent_up(); string messageType = (*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL"; - f_service_client << indent() << "thrift_protocol_write_binary(" << endl; + f_service_client << indent() << "thrift_protocol_write_binary(" << '\n'; indent_up(); - f_service_client << indent() << "$this->output_," << endl - << indent() << "'" << (*f_iter)->get_name() << "'," << endl - << indent() << messageType << "," << endl - << indent() << "$args," << endl - << indent() << "$this->seqid_," << endl - << indent() << "$this->output_->isStrictWrite()" << endl; + f_service_client << indent() << "$this->output_," << '\n' + << indent() << "'" << (*f_iter)->get_name() << "'," << '\n' + << indent() << messageType << "," << '\n' + << indent() << "$args," << '\n' + << indent() << "$this->seqid_," << '\n' + << indent() << "$this->output_->isStrictWrite()" << '\n'; indent_down(); - f_service_client << indent() << ");" << endl; + f_service_client << indent() << ");" << '\n'; indent_down(); - f_service_client << indent() << "} else {" << endl; + f_service_client << indent() << "} else {" << '\n'; indent_up(); // Serialize the request header if (binary_inline_) { - f_service_client << indent() << "$buff = pack('N', (0x80010000 | " << messageType << "));" << endl - << indent() << "$buff .= pack('N', strlen('" << funname << "'));" << endl - << indent() << "$buff .= '" << funname << "';" << endl << indent() - << "$buff .= pack('N', $this->seqid_);" << endl; + f_service_client << indent() << "$buff = pack('N', (0x80010000 | " << messageType << "));" << '\n' + << indent() << "$buff .= pack('N', strlen('" << funname << "'));" << '\n' + << indent() << "$buff .= '" << funname << "';" << '\n' << indent() + << "$buff .= pack('N', $this->seqid_);" << '\n'; } else { f_service_client << indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", $this->seqid_);" << endl; + << "', " << messageType << ", $this->seqid_);" << '\n'; } // Write to the stream if (binary_inline_) { - f_service_client << indent() << "$args->write($buff);" << endl << indent() - << "$this->output_->write($buff);" << endl << indent() - << "$this->output_->flush();" << endl; + f_service_client << indent() << "$args->write($buff);" << '\n' << indent() + << "$this->output_->write($buff);" << '\n' << indent() + << "$this->output_->flush();" << '\n'; } else { - f_service_client << indent() << "$args->write($this->output_);" << endl << indent() - << "$this->output_->writeMessageEnd();" << endl << indent() - << "$this->output_->getTransport()->flush();" << endl; + f_service_client << indent() << "$args->write($this->output_);" << '\n' << indent() + << "$this->output_->writeMessageEnd();" << '\n' << indent() + << "$this->output_->getTransport()->flush();" << '\n'; } scope_down(f_service_client); @@ -1997,98 +1995,98 @@ void t_php_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_client << endl << indent() << "public function " << function_signature(&recv_function) - << endl; + f_service_client << '\n' << indent() << "public function " << function_signature(&recv_function) + << '\n'; scope_up(f_service_client); f_service_client << indent() << "$bin_accel = ($this->input_ instanceof " << "TBinaryProtocolAccelerated)" - << " && function_exists('thrift_protocol_read_binary');" << endl; + << " && function_exists('thrift_protocol_read_binary');" << '\n'; - f_service_client << indent() << "if ($bin_accel) {" << endl; + f_service_client << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - f_service_client << indent() << "$result = thrift_protocol_read_binary(" << endl; + f_service_client << indent() << "$result = thrift_protocol_read_binary(" << '\n'; indent_up(); - f_service_client << indent() << "$this->input_," << endl - << indent() << "'" << resultname << "'," << endl - << indent() << "$this->input_->isStrictRead()" << endl; + f_service_client << indent() << "$this->input_," << '\n' + << indent() << "'" << resultname << "'," << '\n' + << indent() << "$this->input_->isStrictRead()" << '\n'; indent_down(); - f_service_client << indent() << ");" << endl; + f_service_client << indent() << ");" << '\n'; indent_down(); - f_service_client << indent() << "} else {" << endl; + f_service_client << indent() << "} else {" << '\n'; indent_up(); - f_service_client << indent() << "$rseqid = 0;" << endl - << indent() << "$fname = null;" << endl - << indent() << "$mtype = 0;" << endl << endl; + f_service_client << indent() << "$rseqid = 0;" << '\n' + << indent() << "$fname = null;" << '\n' + << indent() << "$mtype = 0;" << '\n' << '\n'; if (binary_inline_) { t_field ffname(g_type_string, "fname"); t_field fseqid(g_type_i32, "rseqid"); - f_service_client << indent() << "$ver = unpack('N', $this->input_->readAll(4));" << endl - << indent() << "$ver = $ver[1];" << endl << indent() << "$mtype = $ver & 0xff;" - << endl << indent() << "$ver = $ver & 0xffff0000;" << endl << indent() + f_service_client << indent() << "$ver = unpack('N', $this->input_->readAll(4));" << '\n' + << indent() << "$ver = $ver[1];" << '\n' << indent() << "$mtype = $ver & 0xff;" + << '\n' << indent() << "$ver = $ver & 0xffff0000;" << '\n' << indent() << "if ($ver != 0x80010000) throw new " << "TProtocolException('Bad version identifier: '.$ver, " - << "TProtocolException::BAD_VERSION);" << endl; + << "TProtocolException::BAD_VERSION);" << '\n'; generate_deserialize_field(f_service_client, &ffname, "", true); generate_deserialize_field(f_service_client, &fseqid, "", true); } else { - f_service_client << indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << endl - << indent() << "if ($mtype == TMessageType::EXCEPTION) {" << endl; + f_service_client << indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << '\n' + << indent() << "if ($mtype == TMessageType::EXCEPTION) {" << '\n'; indent_up(); - f_service_client << indent() << "$x = new TApplicationException();" << endl - << indent() << "$x->read($this->input_);" << endl - << indent() << "$this->input_->readMessageEnd();" << endl - << indent() << "throw $x;" << endl; + f_service_client << indent() << "$x = new TApplicationException();" << '\n' + << indent() << "$x->read($this->input_);" << '\n' + << indent() << "$this->input_->readMessageEnd();" << '\n' + << indent() << "throw $x;" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } - f_service_client << indent() << "$result = new " << resultname << "();" << endl - << indent() << "$result->read($this->input_);" << endl; + f_service_client << indent() << "$result = new " << resultname << "();" << '\n' + << indent() << "$result->read($this->input_);" << '\n'; if (!binary_inline_) { - f_service_client << indent() << "$this->input_->readMessageEnd();" << endl; + f_service_client << indent() << "$this->input_->readMessageEnd();" << '\n'; } scope_down(f_service_client); // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_client << indent() << "if ($result->success !== null) {" << endl; + f_service_client << indent() << "if ($result->success !== null) {" << '\n'; indent_up(); - f_service_client << indent() << "return $result->success;" << endl; + f_service_client << indent() << "return $result->success;" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_client << indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << endl; + f_service_client << indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << '\n'; indent_up(); - f_service_client << indent() << "throw $result->" << (*x_iter)->get_name() << ";" << endl; + f_service_client << indent() << "throw $result->" << (*x_iter)->get_name() << ";" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_client) << "return;" << endl; + indent(f_service_client) << "return;" << '\n'; } else { f_service_client << indent() << "throw new \\Exception(\"" << (*f_iter)->get_name() - << " failed: unknown result\");" << endl; + << " failed: unknown result\");" << '\n'; } // Close function @@ -2097,7 +2095,7 @@ void t_php_generator::generate_service_client(t_service* tservice) { } indent_down(); - f_service_client << "}" << endl; + f_service_client << "}" << '\n'; // Close service client file if (!classmap_) { @@ -2138,54 +2136,54 @@ void t_php_generator::generate_deserialize_field(ostream& out, throw "compiler error: cannot serialize void field in a struct: " + name; break; case t_base_type::TYPE_STRING: - out << indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << endl - << indent() << "$len = $len[1];" << endl << indent() << "if ($len > 0x7fffffff) {" - << endl << indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = " << itrans << "->readAll($len);" - << endl; + out << indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << '\n' + << indent() << "$len = $len[1];" << '\n' << indent() << "if ($len > 0x7fffffff) {" + << '\n' << indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = " << itrans << "->readAll($len);" + << '\n'; break; case t_base_type::TYPE_BOOL: out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" - << endl << indent() << "$" << name << " = (bool)$" << name << "[1];" << endl; + << '\n' << indent() << "$" << name << " = (bool)$" << name << "[1];" << '\n'; break; case t_base_type::TYPE_I8: out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" - << endl << indent() << "$" << name << " = $" << name << "[1];" << endl; + << '\n' << indent() << "$" << name << " = $" << name << "[1];" << '\n'; break; case t_base_type::TYPE_I16: - out << indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << endl - << indent() << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fff) {" - << endl << indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << '\n' + << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fff) {" + << '\n' << indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n'; break; case t_base_type::TYPE_I32: - out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl - << indent() << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fffffff) {" - << endl << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n' + << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {" + << '\n' << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n'; break; case t_base_type::TYPE_I64: - out << indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << endl - << indent() << "if ($arr[1] & 0x80000000) {" << endl << indent() - << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << endl << indent() - << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << endl << indent() << " $" << name - << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << endl << indent() << "} else {" - << endl << indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << endl - << indent() << "}" << endl; + out << indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << '\n' + << indent() << "if ($arr[1] & 0x80000000) {" << '\n' << indent() + << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << '\n' << indent() + << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << '\n' << indent() << " $" << name + << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << '\n' << indent() << "} else {" + << '\n' << indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << '\n' + << indent() << "}" << '\n'; break; case t_base_type::TYPE_DOUBLE: - out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << endl - << indent() << "$" << name << " = $arr[1];" << endl; + out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << '\n' + << indent() << "$" << name << " = $arr[1];" << '\n'; break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase) + tfield->get_name(); } } else if (type->is_enum()) { - out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << indent() - << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fffffff) {" << endl - << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << indent() << "}" - << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n' << indent() + << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {" << '\n' + << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent() << "}" + << '\n' << indent() << "$" << name << " = $val;" << '\n'; } } else { @@ -2224,7 +2222,7 @@ void t_php_generator::generate_deserialize_field(ostream& out, } else if (type->is_enum()) { out << "readI32($" << name << ");"; } - out << endl; + out << '\n'; } } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -2242,8 +2240,8 @@ void t_php_generator::generate_deserialize_field(ostream& out, */ void t_php_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << "$" << prefix << " = new " << php_namespace(tstruct->get_program()) - << tstruct->get_name() << "();" << endl << indent() << "$xfer += $" << prefix - << "->read($input);" << endl; + << tstruct->get_name() << "();" << '\n' << indent() << "$xfer += $" << prefix + << "->read($input);" << '\n'; } void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -2257,44 +2255,44 @@ void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << indent() << "$" << prefix << " = array();" << endl << indent() << "$" << size << " = 0;" - << endl; + out << indent() << "$" << prefix << " = array();" << '\n' << indent() << "$" << size << " = 0;" + << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "$" << ktype << " = 0;" << endl << indent() << "$" << vtype << " = 0;" - << endl; + out << indent() << "$" << ktype << " = 0;" << '\n' << indent() << "$" << vtype << " = 0;" + << '\n'; if (binary_inline_) { generate_deserialize_field(out, &fktype); generate_deserialize_field(out, &fvtype); generate_deserialize_field(out, &fsize); } else { out << indent() << "$xfer += $input->readMapBegin(" - << "$" << ktype << ", $" << vtype << ", $" << size << ");" << endl; + << "$" << ktype << ", $" << vtype << ", $" << size << ");" << '\n'; } } else if (ttype->is_set()) { if (binary_inline_) { generate_deserialize_field(out, &fetype); generate_deserialize_field(out, &fsize); } else { - out << indent() << "$" << etype << " = 0;" << endl << indent() + out << indent() << "$" << etype << " = 0;" << '\n' << indent() << "$xfer += $input->readSetBegin(" - << "$" << etype << ", $" << size << ");" << endl; + << "$" << etype << ", $" << size << ");" << '\n'; } } else if (ttype->is_list()) { if (binary_inline_) { generate_deserialize_field(out, &fetype); generate_deserialize_field(out, &fsize); } else { - out << indent() << "$" << etype << " = 0;" << endl << indent() + out << indent() << "$" << etype << " = 0;" << '\n' << indent() << "$xfer += $input->readListBegin(" - << "$" << etype << ", $" << size << ");" << endl; + << "$" << etype << ", $" << size << ");" << '\n'; } } // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for ($" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ") {" << endl; + indent(out) << "for ($" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ") {" << '\n'; indent_up(); @@ -2311,11 +2309,11 @@ void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype if (!binary_inline_) { // Read container end if (ttype->is_map()) { - indent(out) << "$xfer += $input->readMapEnd();" << endl; + indent(out) << "$xfer += $input->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $input->readSetEnd();" << endl; + indent(out) << "$xfer += $input->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $input->readListEnd();" << endl; + indent(out) << "$xfer += $input->readListEnd();" << '\n'; } } } @@ -2329,28 +2327,28 @@ void t_php_generator::generate_deserialize_map_element(ostream& out, t_map* tmap t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, true, true) << endl; - indent(out) << declare_field(&fval, true, true) << endl; + indent(out) << declare_field(&fkey, true, true) << '\n'; + indent(out) << declare_field(&fval, true, true) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << endl; + indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << '\n'; } void t_php_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << "$" << elem << " = null;" << endl; + indent(out) << "$" << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); t_type* elem_type = tset->get_elem_type(); if(php_is_scalar(elem_type)) { - indent(out) << "$" << prefix << "[$" << elem << "] = true;" << endl; + indent(out) << "$" << prefix << "[$" << elem << "] = true;" << '\n'; } else { - indent(out) << "$" << prefix << "[] = $" << elem << ";" << endl; + indent(out) << "$" << prefix << "[] = $" << elem << ";" << '\n'; } } @@ -2360,11 +2358,11 @@ void t_php_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << "$" << elem << " = null;" << endl; + indent(out) << "$" << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "$" << prefix << " []= $" << elem << ";" << endl; + indent(out) << "$" << prefix << " []= $" << elem << ";" << '\n'; } /** @@ -2397,33 +2395,33 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st throw "compiler error: cannot serialize void field in a struct: " + name; break; case t_base_type::TYPE_STRING: - out << indent() << "$output .= pack('N', strlen($" << name << "));" << endl << indent() - << "$output .= $" << name << ";" << endl; + out << indent() << "$output .= pack('N', strlen($" << name << "));" << '\n' << indent() + << "$output .= $" << name << ";" << '\n'; break; case t_base_type::TYPE_BOOL: - out << indent() << "$output .= pack('c', $" << name << " ? 1 : 0);" << endl; + out << indent() << "$output .= pack('c', $" << name << " ? 1 : 0);" << '\n'; break; case t_base_type::TYPE_I8: - out << indent() << "$output .= pack('c', $" << name << ");" << endl; + out << indent() << "$output .= pack('c', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I16: - out << indent() << "$output .= pack('n', $" << name << ");" << endl; + out << indent() << "$output .= pack('n', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I32: - out << indent() << "$output .= pack('N', $" << name << ");" << endl; + out << indent() << "$output .= pack('N', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I64: out << indent() << "$output .= pack('N2', $" << name << " >> 32, $" << name - << " & 0xFFFFFFFF);" << endl; + << " & 0xFFFFFFFF);" << '\n'; break; case t_base_type::TYPE_DOUBLE: - out << indent() << "$output .= strrev(pack('d', $" << name << "));" << endl; + out << indent() << "$output .= strrev(pack('d', $" << name << "));" << '\n'; break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - out << indent() << "$output .= pack('N', $" << name << ");" << endl; + out << indent() << "$output .= pack('N', $" << name << ");" << '\n'; } } else { @@ -2462,7 +2460,7 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st } else if (type->is_enum()) { out << "writeI32($" << name << ");"; } - out << endl; + out << '\n'; } } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -2480,7 +2478,7 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st */ void t_php_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << "$xfer += $" << prefix << "->write($output);" << endl; + indent(out) << "$xfer += $" << prefix << "->write($output);" << '\n'; } /** @@ -2490,35 +2488,35 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_map*)ttype)->get_key_type()) - << ");" << endl << indent() << "$output .= pack('c', " - << type_to_enum(((t_map*)ttype)->get_val_type()) << ");" << endl << indent() - << "$output .= strrev(pack('l', count($" << prefix << ")));" << endl; + << ");" << '\n' << indent() << "$output .= pack('c', " + << type_to_enum(((t_map*)ttype)->get_val_type()) << ");" << '\n' << indent() + << "$output .= strrev(pack('l', count($" << prefix << ")));" << '\n'; } else { indent(out) << "$output->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } else if (ttype->is_set()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ");" << endl << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" - << endl; + << ");" << '\n' << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" + << '\n'; } else { indent(out) << "$output->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } else if (ttype->is_list()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_list*)ttype)->get_elem_type()) - << ");" << endl << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" - << endl; + << ");" << '\n' << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" + << '\n'; } else { indent(out) << "$output->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } @@ -2526,14 +2524,14 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, string kiter = tmp("kiter"); string viter = tmp("viter"); indent(out) << "foreach ($" << prefix << " as " - << "$" << kiter << " => $" << viter << ") {" << endl; + << "$" << kiter << " => $" << viter << ") {" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); scope_down(out); } else if (ttype->is_set()) { string iter = tmp("iter"); string iter_val = tmp("iter"); - indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << iter_val << ") {" << endl; + indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << iter_val << ") {" << '\n'; indent_up(); t_type* elem_type = ((t_set*)ttype)->get_elem_type(); @@ -2545,7 +2543,7 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "foreach ($" << prefix << " as $" << iter << ") {" << endl; + indent(out) << "foreach ($" << prefix << " as $" << iter << ") {" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); @@ -2553,11 +2551,11 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, if (!binary_inline_) { if (ttype->is_map()) { - indent(out) << "$output->writeMapEnd();" << endl; + indent(out) << "$output->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$output->writeSetEnd();" << endl; + indent(out) << "$output->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$output->writeListEnd();" << endl; + indent(out) << "$output->writeListEnd();" << '\n'; } } } @@ -2617,12 +2615,12 @@ void t_php_generator::generate_php_doc(ostream& out, t_field* field) { // prepend free-style doc if available if (field->has_doc()) { - ss << field->get_doc() << endl; + ss << field->get_doc() << '\n'; } // append @var tag t_type* type = get_true_type(field->get_type()); - ss << "@var " << type_to_phpdoc(type) << endl; + ss << "@var " << type_to_phpdoc(type) << '\n'; generate_php_docstring_comment(out, ss.str()); } @@ -2633,7 +2631,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_field* field) { void t_php_generator::generate_php_doc(ostream& out, t_function* function) { stringstream ss; if (function->has_doc()) { - ss << function->get_doc() << endl; + ss << function->get_doc() << '\n'; } // generate parameter types doc @@ -2645,7 +2643,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (arg->has_doc()) { ss << " " << arg->get_doc(); } - ss << endl; + ss << '\n'; } // generate return type doc @@ -2655,7 +2653,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (ret_type->has_doc()) { ss << " " << ret_type->get_doc(); } - ss << endl; + ss << '\n'; } // generate exceptions doc @@ -2667,7 +2665,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (exc->has_doc()) { ss << " " << exc->get_doc(); } - ss << endl; + ss << '\n'; } generate_docstring_comment(out, "/**\n", " * ", ss.str(), " */\n"); diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc index ffabd56521f..f8fb9f871ff 100644 --- a/compiler/cpp/src/thrift/generate/t_py_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc @@ -40,8 +40,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Python code generator. * @@ -65,6 +63,7 @@ class t_py_generator : public t_generator { gen_twisted_ = false; gen_dynamic_ = false; gen_enum_ = false; + gen_type_hints_ = false; coding_ = ""; gen_dynbaseclass_ = ""; gen_dynbaseclass_exc_ = ""; @@ -127,6 +126,11 @@ class t_py_generator : public t_generator { gen_tornado_ = true; } else if( iter->first.compare("coding") == 0) { coding_ = iter->second; + } else if (iter->first.compare("type_hints") == 0) { + if (!gen_enum_) { + throw "the type_hints py option requires the enum py option"; + } + gen_type_hints_ = true; } else { throw "unknown option py:" + iter->first; } @@ -254,12 +258,16 @@ class t_py_generator : public t_generator { std::string declare_argument(t_field* tfield); std::string render_field_default_value(t_field* tfield); std::string type_name(t_type* ttype); - std::string function_signature(t_function* tfunction, bool interface = false); + std::string function_signature(t_function* tfunction, bool interface = false, bool send_part = false); std::string argument_list(t_struct* tstruct, std::vector* pre = nullptr, std::vector* post = nullptr); std::string type_to_enum(t_type* ttype); std::string type_to_spec_args(t_type* ttype); + std::string type_to_py_type(t_type* type); + std::string member_hint(t_type* type, t_field::e_req req); + std::string arg_hint(t_type* type); + std::string func_hint(t_type* type); static bool is_valid_namespace(const std::string& sub_namespace) { return sub_namespace == "twisted"; @@ -316,6 +324,11 @@ class t_py_generator : public t_generator { bool gen_slots_; + /** + * True if we should generate classes type hints and type checks in write methods. + */ + bool gen_type_hints_; + std::string copy_options_; /** @@ -414,22 +427,26 @@ void t_py_generator::init_generator() { for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { f_init << ", '" << (*sv_iter)->get_name() << "'"; } - f_init << "]" << endl; + f_init << "]" << '\n'; f_init.close(); // Print header - f_types_ << py_autogen_comment() << endl - << py_imports() << endl - << render_includes() << endl - << "from thrift.transport import TTransport" << endl + f_types_ << py_autogen_comment() << '\n' + << py_imports() << '\n' + << render_includes() << '\n' + << "from thrift.transport import TTransport" << '\n' << import_dynbase_; - f_types_ << "all_structs = []" << endl; + if (gen_type_hints_) { + f_types_ << "all_structs: list[typing.Any] = []" << '\n'; + } else { + f_types_ << "all_structs = []" << '\n'; + } f_consts_ << - py_autogen_comment() << endl << - py_imports() << endl << - "from .ttypes import *" << endl; + py_autogen_comment() << '\n' << + py_imports() << '\n' << + "from .ttypes import *" << '\n'; } /** @@ -462,18 +479,24 @@ string t_py_generator::py_autogen_comment() { */ string t_py_generator::py_imports() { ostringstream ss; + if (gen_type_hints_) { + ss << "from __future__ import annotations" << '\n' << "import typing" << '\n'; + } + ss << "from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, " "TApplicationException" - << endl + << '\n' << "from thrift.protocol.TProtocol import TProtocolException" - << endl + << '\n' << "from thrift.TRecursive import fix_spec" - << endl; + << '\n' + << "from uuid import UUID" + << '\n'; if (gen_enum_) { - ss << "from enum import IntEnum" << endl; + ss << "from enum import IntEnum" << '\n'; } if (gen_utf8strings_) { - ss << endl << "import sys"; + ss << '\n' << "import sys"; } return ss.str(); } @@ -484,8 +507,8 @@ string t_py_generator::py_imports() { void t_py_generator::close_generator() { // Fix thrift_spec definitions for recursive structs. - f_types_ << "fix_spec(all_structs)" << endl; - f_types_ << "del all_structs" << endl; + f_types_ << "fix_spec(all_structs)" << '\n'; + f_types_ << "del all_structs" << '\n'; // Close types file f_types_.close(); @@ -519,37 +542,37 @@ void t_py_generator::generate_enum(t_enum* tenum) { base_class = gen_dynbaseclass_; } - f_types_ << endl - << endl + f_types_ << '\n' + << '\n' << "class " << tenum->get_name() << (base_class.empty() ? "" : "(" + base_class + ")") << ":" - << endl; + << '\n'; indent_up(); generate_python_docstring(f_types_, tenum); - to_string_mapping << indent() << "_VALUES_TO_NAMES = {" << endl; - from_string_mapping << indent() << "_NAMES_TO_VALUES = {" << endl; + to_string_mapping << indent() << "_VALUES_TO_NAMES = {" << '\n'; + from_string_mapping << indent() << "_NAMES_TO_VALUES = {" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_types_) << (*c_iter)->get_name() << " = " << value << endl; + indent(f_types_) << (*c_iter)->get_name() << " = " << value << '\n'; // Dictionaries to/from string names of enums to_string_mapping << indent() << indent() << value << ": \"" - << escape_string((*c_iter)->get_name()) << "\"," << endl; + << escape_string((*c_iter)->get_name()) << "\"," << '\n'; from_string_mapping << indent() << indent() << '"' << escape_string((*c_iter)->get_name()) - << "\": " << value << ',' << endl; + << "\": " << value << ',' << '\n'; } - to_string_mapping << indent() << "}" << endl; - from_string_mapping << indent() << "}" << endl; + to_string_mapping << indent() << "}" << '\n'; + from_string_mapping << indent() << "}" << '\n'; indent_down(); - f_types_ << endl; + f_types_ << '\n'; if (!gen_enum_) { - f_types_ << to_string_mapping.str() << endl << from_string_mapping.str(); + f_types_ << to_string_mapping.str() << '\n' << from_string_mapping.str(); } } @@ -562,7 +585,7 @@ void t_py_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); indent(f_consts_) << name << " = " << render_const_value(type, value); - f_consts_ << endl; + f_consts_ << '\n'; } /** @@ -599,6 +622,9 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << emit_double_as_string(value->get_double()); } break; + case t_base_type::TYPE_UUID: + out << "UUID(\"" << get_escaped_string(value) << "\")"; + break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } @@ -612,7 +638,7 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << int_val; } } else if (type->is_struct() || type->is_xception()) { - out << type_name(type) << "(**{" << endl; + out << type_name(type) << "(**{" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -629,7 +655,7 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } indent(out) << render_const_value(g_type_string, v_iter->first) << ": " - << render_const_value(field_type, v_iter->second) << "," << endl; + << render_const_value(field_type, v_iter->second) << "," << '\n'; } indent_down(); indent(out) << "})"; @@ -639,13 +665,13 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { if (is_immutable(type)) { out << "TFrozenDict("; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { indent(out) << render_const_value(ktype, v_iter->first) << ": " - << render_const_value(vtype, v_iter->second) << "," << endl; + << render_const_value(vtype, v_iter->second) << "," << '\n'; } indent_down(); indent(out) << "}"; @@ -666,15 +692,15 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << "set("; } if (is_immutable(type) || type->is_set()) { - out << "(" << endl; + out << "(" << '\n'; } else { - out << "[" << endl; + out << "[" << '\n'; } indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - indent(out) << render_const_value(etype, *v_iter) << "," << endl; + indent(out) << render_const_value(etype, *v_iter) << "," << '\n'; } indent_down(); if (is_immutable(type) || type->is_set()) { @@ -743,17 +769,17 @@ void t_py_generator::generate_py_thrift_spec(ostream& out, vector::const_iterator m_iter; // Add struct definition to list so thrift_spec can be fixed for recursive structures. - indent(out) << "all_structs.append(" << tstruct->get_name() << ")" << endl; + indent(out) << "all_structs.append(" << tstruct->get_name() << ")" << '\n'; if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) { - indent(out) << tstruct->get_name() << ".thrift_spec = (" << endl; + indent(out) << tstruct->get_name() << ".thrift_spec = (" << '\n'; indent_up(); int sorted_keys_pos = 0; for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) { for (; sorted_keys_pos != (*m_iter)->get_key(); sorted_keys_pos++) { - indent(out) << "None, # " << sorted_keys_pos << endl; + indent(out) << "None, # " << sorted_keys_pos << '\n'; } indent(out) << "(" << (*m_iter)->get_key() << ", " << type_to_enum((*m_iter)->get_type()) @@ -762,15 +788,15 @@ void t_py_generator::generate_py_thrift_spec(ostream& out, << ", " << type_to_spec_args((*m_iter)->get_type()) << ", " << render_field_default_value(*m_iter) << ", " << ")," - << " # " << sorted_keys_pos << endl; + << " # " << sorted_keys_pos << '\n'; sorted_keys_pos++; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } else { - indent(out) << tstruct->get_name() << ".thrift_spec = ()" << endl; + indent(out) << tstruct->get_name() << ".thrift_spec = ()" << '\n'; } } @@ -786,7 +812,7 @@ void t_py_generator::generate_py_struct_definition(ostream& out, const vector& sorted_members = tstruct->get_sorted_members(); vector::const_iterator m_iter; - out << endl << endl << "class " << tstruct->get_name(); + out << '\n' << '\n' << "class " << tstruct->get_name(); if (is_exception) { if (gen_dynamic_) { if (is_immutable(tstruct)) { @@ -806,11 +832,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } else if (gen_newstyle_) { out << "(object)"; } - out << ":" << endl; + out << ":" << '\n'; indent_up(); generate_python_docstring(out, tstruct); + std::string thrift_spec_type = gen_type_hints_ ? ": typing.Any" : ""; + out << indent() << "thrift_spec" << thrift_spec_type << " = None" << '\n'; - out << endl; + out << '\n'; /* Here we generate the structure specification for the fastbinary codec. @@ -833,13 +861,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, */ if (gen_slots_) { - indent(out) << "__slots__ = (" << endl; + indent(out) << "__slots__ = (" << '\n'; indent_up(); for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) { - indent(out) << "'" << (*m_iter)->get_name() << "'," << endl; + indent(out) << "'" << (*m_iter)->get_name() << "'," << '\n'; } indent_down(); - indent(out) << ")" << endl << endl; + indent(out) << ")" << '\n' << '\n'; } // TODO(dreiss): Look into generating an empty tuple instead of None @@ -848,13 +876,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // don't have thrift_spec. if (members.size() > 0) { - out << endl; + out << '\n'; out << indent() << "def __init__(self,"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { out << " " << declare_argument(*m_iter) << ","; } - out << "):" << endl; + out << "):" << '\n'; indent_up(); @@ -863,10 +891,10 @@ void t_py_generator::generate_py_struct_definition(ostream& out, t_type* type = (*m_iter)->get_type(); if (!type->is_base_type() && !type->is_enum() && (*m_iter)->get_value() != nullptr) { indent(out) << "if " << (*m_iter)->get_name() << " is " - << "self.thrift_spec[" << (*m_iter)->get_key() << "][4]:" << endl; + << "self.thrift_spec[" << (*m_iter)->get_key() << "][4]:" << '\n'; indent_up(); indent(out) << (*m_iter)->get_name() << " = " << render_field_default_value(*m_iter) - << endl; + << '\n'; indent_down(); } @@ -875,16 +903,18 @@ void t_py_generator::generate_py_struct_definition(ostream& out, indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('" << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << " if hasattr(" << (*m_iter)->get_name() << ", 'value') else " - << type_name(type) << ".__members__.get(" << (*m_iter)->get_name() << "))" << endl; + << type_name(type) << ".__members__.get(" << (*m_iter)->get_name() << "))" << '\n'; } else if (gen_newstyle_ || gen_dynamic_) { indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('" - << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << ")" << endl; + << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << ")" << '\n'; } else { indent(out) << "self.__dict__['" << (*m_iter)->get_name() - << "'] = " << (*m_iter)->get_name() << endl; + << "'] = " << (*m_iter)->get_name() << '\n'; } } else { - indent(out) << "self." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << endl; + indent(out) << "self." << (*m_iter)->get_name() + << member_hint((*m_iter)->get_type(), (*m_iter)->get_req()) << " = " + << (*m_iter)->get_name() << '\n'; } } @@ -892,8 +922,8 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } if (is_immutable(tstruct)) { - out << endl; - out << indent() << "def __setattr__(self, *args):" << endl; + out << '\n'; + out << indent() << "def __setattr__(self, *args):" << '\n'; indent_up(); // Not user-provided fields should be editable so that the Python Standard Library can edit @@ -902,16 +932,16 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // trivial because we know which fields are user-provided, without slots we need to build a // way to know which fields are user-provided. if (gen_slots_ && !gen_dynamic_) { - out << indent() << "if args[0] not in self.__slots__:" << endl; + out << indent() << "if args[0] not in self.__slots__:" << '\n'; indent_up(); - out << indent() << "super().__setattr__(*args)" << endl - << indent() << "return" << endl; + out << indent() << "super().__setattr__(*args)" << '\n' + << indent() << "return" << '\n'; indent_down(); } - out << indent() << "raise TypeError(\"can't modify immutable instance\")" << endl; + out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n'; indent_down(); - out << endl; - out << indent() << "def __delattr__(self, *args):" << endl; + out << '\n'; + out << indent() << "def __delattr__(self, *args):" << '\n'; indent_up(); // Not user-provided fields should be editable so that the Python Standard Library can edit @@ -920,26 +950,26 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // trivial because we know which fields are user-provided, without slots we need to build a // way to know which fields are user-provided. if (gen_slots_ && !gen_dynamic_) { - out << indent() << "if args[0] not in self.__slots__:" << endl; + out << indent() << "if args[0] not in self.__slots__:" << '\n'; indent_up(); - out << indent() << "super().__delattr__(*args)" << endl - << indent() << "return" << endl; + out << indent() << "super().__delattr__(*args)" << '\n' + << indent() << "return" << '\n'; indent_down(); } - out << indent() << "raise TypeError(\"can't modify immutable instance\")" << endl; + out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n'; indent_down(); - out << endl; + out << '\n'; // Hash all of the members in order, and also hash in the class // to avoid collisions for stuff like single-field structures. - out << indent() << "def __hash__(self):" << endl + out << indent() << "def __hash__(self):" << '\n' << indent() << indent_str() << "return hash(self.__class__) ^ hash(("; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { out << "self." << (*m_iter)->get_name() << ", "; } - out << "))" << endl; + out << "))" << '\n'; } else if (gen_enum_) { bool has_enum = false; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -951,25 +981,25 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } if (has_enum) { - out << endl; - indent(out) << "def __setattr__(self, name, value):" << endl; + out << '\n'; + indent(out) << "def __setattr__(self, name, value):" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = (*m_iter)->get_type(); if (type->is_enum()) { - out << indent() << "if name == \"" << (*m_iter)->get_name() << "\":" << endl - << indent() << indent_str() << "super().__setattr__(name, value if hasattr(value, 'value') else " - << type_name(type) << ".__members__.get(value))" << endl - << indent() << indent_str() << "return" << endl; + out << indent() << "if name == \"" << (*m_iter)->get_name() << "\":" << '\n' + << indent() << indent_str() << "super().__setattr__(name, value if hasattr(value, 'value') or value is None else " + << type_name(type) << "(value))" << '\n' + << indent() << indent_str() << "return" << '\n'; } } - indent(out) << "super().__setattr__(name, value)" << endl << endl; + indent(out) << "super().__setattr__(name, value)" << '\n' << '\n'; indent_down(); } } if (!gen_dynamic_) { - out << endl; + out << '\n'; generate_py_struct_reader(out, tstruct); generate_py_struct_writer(out, tstruct); } @@ -978,64 +1008,64 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // because when raised exceptions are printed to the console, __repr__ // isn't used. See python bug #5882 if (is_exception) { - out << endl; - out << indent() << "def __str__(self):" << endl - << indent() << indent_str() << "return repr(self)" << endl; + out << '\n'; + out << indent() << "def __str__(self):" << '\n' + << indent() << indent_str() << "return repr(self)" << '\n'; } if (!gen_slots_) { - out << endl; + out << '\n'; // Printing utilities so that on the command line thrift // structs look pretty like dictionaries - indent(out) << "def __repr__(self):" << endl; + indent(out) << "def __repr__(self):" << '\n'; indent_up(); - out << indent() << "L = ['%s=%r' % (key, value)" << endl - << indent() << " for key, value in self.__dict__.items()]" << endl - << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << endl - << endl; + out << indent() << "L = ['%s=%r' % (key, value)" << '\n' + << indent() << " for key, value in self.__dict__.items()]" << '\n' + << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << '\n' + << '\n'; indent_down(); // Equality and inequality methods that compare by value - out << indent() << "def __eq__(self, other):" << endl; + out << indent() << "def __eq__(self, other):" << '\n'; indent_up(); out << indent() << "return isinstance(other, self.__class__) and " - "self.__dict__ == other.__dict__" << endl; + "self.__dict__ == other.__dict__" << '\n'; indent_down(); - out << endl; + out << '\n'; - out << indent() << "def __ne__(self, other):" << endl; + out << indent() << "def __ne__(self, other):" << '\n'; indent_up(); - out << indent() << "return not (self == other)" << endl; + out << indent() << "return not (self == other)" << '\n'; indent_down(); } else if (!gen_dynamic_) { - out << endl; + out << '\n'; // no base class available to implement __eq__ and __repr__ and __ne__ for us // so we must provide one that uses __slots__ - indent(out) << "def __repr__(self):" << endl; + indent(out) << "def __repr__(self):" << '\n'; indent_up(); - out << indent() << "L = ['%s=%r' % (key, getattr(self, key))" << endl - << indent() << " for key in self.__slots__]" << endl - << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << endl - << endl; + out << indent() << "L = ['%s=%r' % (key, getattr(self, key))" << '\n' + << indent() << " for key in self.__slots__]" << '\n' + << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << '\n' + << '\n'; indent_down(); // Equality method that compares each attribute by value and type, walking __slots__ - out << indent() << "def __eq__(self, other):" << endl; + out << indent() << "def __eq__(self, other):" << '\n'; indent_up(); - out << indent() << "if not isinstance(other, self.__class__):" << endl - << indent() << indent_str() << "return False" << endl - << indent() << "for attr in self.__slots__:" << endl - << indent() << indent_str() << "my_val = getattr(self, attr)" << endl - << indent() << indent_str() << "other_val = getattr(other, attr)" << endl - << indent() << indent_str() << "if my_val != other_val:" << endl - << indent() << indent_str() << indent_str() << "return False" << endl - << indent() << "return True" << endl - << endl; + out << indent() << "if not isinstance(other, self.__class__):" << '\n' + << indent() << indent_str() << "return False" << '\n' + << indent() << "for attr in self.__slots__:" << '\n' + << indent() << indent_str() << "my_val = getattr(self, attr)" << '\n' + << indent() << indent_str() << "other_val = getattr(other, attr)" << '\n' + << indent() << indent_str() << "if my_val != other_val:" << '\n' + << indent() << indent_str() << indent_str() << "return False" << '\n' + << indent() << "return True" << '\n' + << '\n'; indent_down(); - out << indent() << "def __ne__(self, other):" << endl - << indent() << indent_str() << "return not (self == other)" << endl; + out << indent() << "def __ne__(self, other):" << '\n' + << indent() << indent_str() << "return not (self == other)" << '\n'; } indent_down(); } @@ -1048,9 +1078,9 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (is_immutable(tstruct)) { - out << indent() << "@classmethod" << endl << indent() << "def read(cls, iprot):" << endl; + out << indent() << "@classmethod" << '\n' << indent() << "def read(cls, iprot):" << '\n'; } else { - indent(out) << "def read(self, iprot):" << endl; + indent(out) << "def read(self, iprot):" << '\n'; } indent_up(); @@ -1059,18 +1089,18 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) indent(out) << "if iprot._fast_decode is not None " "and isinstance(iprot.trans, TTransport.CReadableTransport) " "and " - << id << ".thrift_spec is not None:" << endl; + << id << ".thrift_spec is not None:" << '\n'; indent_up(); if (is_immutable(tstruct)) { - indent(out) << "return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])" << endl; + indent(out) << "return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])" << '\n'; } else { - indent(out) << "iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])" << endl; - indent(out) << "return" << endl; + indent(out) << "iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])" << '\n'; + indent(out) << "return" << '\n'; } indent_down(); - indent(out) << "iprot.readStructBegin()" << endl; + indent(out) << "iprot.readStructBegin()" << '\n'; if (is_immutable(tstruct)) { for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1082,21 +1112,21 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) } else { result << "None"; } - indent(out) << result.str() << endl; + indent(out) << result.str() << '\n'; } } // Loop over reading in fields - indent(out) << "while True:" << endl; + indent(out) << "while True:" << '\n'; indent_up(); // Read beginning field marker - indent(out) << "(fname, ftype, fid) = iprot.readFieldBegin()" << endl; + indent(out) << "(fname, ftype, fid) = iprot.readFieldBegin()" << '\n'; // Check for field STOP marker and break - indent(out) << "if ftype == TType.STOP:" << endl; + indent(out) << "if ftype == TType.STOP:" << '\n'; indent_up(); - indent(out) << "break" << endl; + indent(out) << "break" << '\n'; indent_down(); // Switch statement on the field we are reading @@ -1110,9 +1140,9 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) } else { out << indent() << "elif "; } - out << "fid == " << (*f_iter)->get_key() << ":" << endl; + out << "fid == " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << ":" << endl; + indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << ":" << '\n'; indent_up(); if (is_immutable(tstruct)) { generate_deserialize_field(out, *f_iter); @@ -1120,32 +1150,32 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) generate_deserialize_field(out, *f_iter, "self."); } indent_down(); - out << indent() << "else:" << endl << indent() << indent_str() << "iprot.skip(ftype)" << endl; + out << indent() << "else:" << '\n' << indent() << indent_str() << "iprot.skip(ftype)" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "else:" << endl << indent() << indent_str() << "iprot.skip(ftype)" << endl; + out << indent() << "else:" << '\n' << indent() << indent_str() << "iprot.skip(ftype)" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd()" << endl; + indent(out) << "iprot.readFieldEnd()" << '\n'; indent_down(); - indent(out) << "iprot.readStructEnd()" << endl; + indent(out) << "iprot.readStructEnd()" << '\n'; if (is_immutable(tstruct)) { - indent(out) << "return cls(" << endl; + indent(out) << "return cls(" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << (*f_iter)->get_name() << "=" << (*f_iter)->get_name() << "," << endl; + indent(out) << (*f_iter)->get_name() << "=" << (*f_iter)->get_name() << "," << '\n'; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } indent_down(); - out << endl; + out << '\n'; } void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) { @@ -1153,49 +1183,49 @@ void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "def write(self, oprot):" << endl; + indent(out) << "def write(self, oprot):" << '\n'; indent_up(); - - indent(out) << "if oprot._fast_encode is not None and self.thrift_spec is not None:" << endl; + indent(out) << "self.validate()" << '\n'; + indent(out) << "if oprot._fast_encode is not None and self.thrift_spec is not None:" << '\n'; indent_up(); indent(out) << "oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))" - << endl; - indent(out) << "return" << endl; + << '\n'; + indent(out) << "return" << '\n'; indent_down(); - indent(out) << "oprot.writeStructBegin('" << name << "')" << endl; + indent(out) << "oprot.writeStructBegin('" << name << "')" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { // Write field header - indent(out) << "if self." << (*f_iter)->get_name() << " is not None:" << endl; + indent(out) << "if self." << (*f_iter)->get_name() << " is not None:" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ")" << endl; + << ", " << (*f_iter)->get_key() << ")" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self."); // Write field closer - indent(out) << "oprot.writeFieldEnd()" << endl; + indent(out) << "oprot.writeFieldEnd()" << '\n'; indent_down(); } // Write the struct map - out << indent() << "oprot.writeFieldStop()" << endl << indent() << "oprot.writeStructEnd()" - << endl; + out << indent() << "oprot.writeFieldStop()" << '\n' << indent() << "oprot.writeStructEnd()" + << '\n'; - out << endl; + out << '\n'; indent_down(); generate_py_struct_required_validator(out, tstruct); } void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struct* tstruct) { - indent(out) << "def validate(self):" << endl; + indent(out) << "def validate(self):" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1206,14 +1236,14 @@ void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struc for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); if (field->get_req() == t_field::T_REQUIRED) { - indent(out) << "if self." << field->get_name() << " is None:" << endl; + indent(out) << "if self." << field->get_name() << " is None:" << '\n'; indent(out) << indent_str() << "raise TProtocolException(message='Required field " - << field->get_name() << " is unset!')" << endl; + << field->get_name() << " is unset!')" << '\n'; } } } - indent(out) << "return" << endl; + indent(out) << "return" << '\n'; indent_down(); } @@ -1226,32 +1256,32 @@ void t_py_generator::generate_service(t_service* tservice) { string f_service_name = package_dir_ + "/" + service_name_ + ".py"; f_service_.open(f_service_name.c_str()); - f_service_ << py_autogen_comment() << endl << py_imports() << endl; + f_service_ << py_autogen_comment() << '\n' << py_imports() << '\n'; if (tservice->get_extends() != nullptr) { f_service_ << "import " << get_real_py_module(tservice->get_extends()->get_program(), gen_twisted_, package_prefix_) << "." - << tservice->get_extends()->get_name() << endl; + << tservice->get_extends()->get_name() << '\n'; } - f_service_ << "import logging" << endl - << "from .ttypes import *" << endl - << "from thrift.Thrift import TProcessor" << endl - << "from thrift.transport import TTransport" << endl + f_service_ << "import logging" << '\n' + << "from .ttypes import *" << '\n' + << "from thrift.Thrift import TProcessor" << '\n' + << "from thrift.transport import TTransport" << '\n' << import_dynbase_; if (gen_zope_interface_) { - f_service_ << "from zope.interface import Interface, implementer" << endl; + f_service_ << "from zope.interface import Interface, implementer" << '\n'; } if (gen_twisted_) { - f_service_ << "from twisted.internet import defer" << endl - << "from thrift.transport import TTwisted" << endl; + f_service_ << "from twisted.internet import defer" << '\n' + << "from thrift.transport import TTwisted" << '\n'; } else if (gen_tornado_) { - f_service_ << "from tornado import gen" << endl; - f_service_ << "from tornado import concurrent" << endl; + f_service_ << "from tornado import gen" << '\n'; + f_service_ << "from tornado import concurrent" << '\n'; } - f_service_ << "all_structs = []" << endl; + f_service_ << "all_structs = []" << '\n'; // Generate the three main parts of the service generate_service_interface(tservice); @@ -1261,8 +1291,8 @@ void t_py_generator::generate_service(t_service* tservice) { generate_service_remote(tservice); // Close service file - f_service_ << "fix_spec(all_structs)" << endl - << "del all_structs" << endl; + f_service_ << "fix_spec(all_structs)" << '\n' + << "del all_structs" << '\n'; f_service_.close(); } @@ -1275,7 +1305,7 @@ void t_py_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << endl << "# HELPER FUNCTIONS AND STRUCTURES" << endl; + f_service_ << '\n' << "# HELPER FUNCTIONS AND STRUCTURES" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1328,12 +1358,12 @@ void t_py_generator::generate_service_interface(t_service* tservice) { } } - f_service_ << endl << endl << "class Iface" << extends_if << ":" << endl; + f_service_ << '\n' << '\n' << "class Iface" << extends_if << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, tservice); vector functions = tservice->get_functions(); if (functions.empty()) { - f_service_ << indent() << "pass" << endl; + f_service_ << indent() << "pass" << '\n'; } else { vector::iterator f_iter; bool first = true; @@ -1341,12 +1371,12 @@ void t_py_generator::generate_service_interface(t_service* tservice) { if (first) { first = false; } else { - f_service_ << endl; + f_service_ << '\n'; } - f_service_ << indent() << "def " << function_signature(*f_iter, true) << ":" << endl; + f_service_ << indent() << "def " << function_signature(*f_iter, true) << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, (*f_iter)); - f_service_ << indent() << "pass" << endl; + f_service_ << indent() << "pass" << '\n'; indent_down(); } } @@ -1375,91 +1405,91 @@ void t_py_generator::generate_service_client(t_service* tservice) { } } - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; if (gen_zope_interface_) { - f_service_ << "@implementer(Iface)" << endl - << "class Client" << extends_client << ":" << endl - << endl; + f_service_ << "@implementer(Iface)" << '\n' + << "class Client" << extends_client << ":" << '\n' + << '\n'; } else { - f_service_ << "class Client(" << extends_client << "Iface):" << endl; + f_service_ << "class Client(" << extends_client << "Iface):" << '\n'; } indent_up(); generate_python_docstring(f_service_, tservice); // Constructor function if (gen_twisted_) { - f_service_ << indent() << "def __init__(self, transport, oprot_factory):" << endl; + f_service_ << indent() << "def __init__(self, transport, oprot_factory):" << '\n'; } else if (gen_tornado_) { f_service_ << indent() - << "def __init__(self, transport, iprot_factory, oprot_factory=None):" << endl; + << "def __init__(self, transport, iprot_factory, oprot_factory=None):" << '\n'; } else { - f_service_ << indent() << "def __init__(self, iprot, oprot=None):" << endl; + f_service_ << indent() << "def __init__(self, iprot, oprot=None):" << '\n'; } indent_up(); if (extends.empty()) { if (gen_twisted_) { - f_service_ << indent() << "self._transport = transport" << endl - << indent() << "self._oprot_factory = oprot_factory" << endl - << indent() << "self._seqid = 0" << endl - << indent() << "self._reqs = {}" << endl; + f_service_ << indent() << "self._transport = transport" << '\n' + << indent() << "self._oprot_factory = oprot_factory" << '\n' + << indent() << "self._seqid = 0" << '\n' + << indent() << "self._reqs = {}" << '\n'; } else if (gen_tornado_) { - f_service_ << indent() << "self._transport = transport" << endl - << indent() << "self._iprot_factory = iprot_factory" << endl + f_service_ << indent() << "self._transport = transport" << '\n' + << indent() << "self._iprot_factory = iprot_factory" << '\n' << indent() << "self._oprot_factory = (oprot_factory if oprot_factory is not None" - << endl - << indent() << " else iprot_factory)" << endl - << indent() << "self._seqid = 0" << endl - << indent() << "self._reqs = {}" << endl + << '\n' + << indent() << " else iprot_factory)" << '\n' + << indent() << "self._seqid = 0" << '\n' + << indent() << "self._reqs = {}" << '\n' << indent() << "self._transport.io_loop.spawn_callback(self._start_receiving)" - << endl; + << '\n'; } else { - f_service_ << indent() << "self._iprot = self._oprot = iprot" << endl - << indent() << "if oprot is not None:" << endl - << indent() << indent_str() << "self._oprot = oprot" << endl - << indent() << "self._seqid = 0" << endl; + f_service_ << indent() << "self._iprot = self._oprot = iprot" << '\n' + << indent() << "if oprot is not None:" << '\n' + << indent() << indent_str() << "self._oprot = oprot" << '\n' + << indent() << "self._seqid = 0" << '\n'; } } else { if (gen_twisted_) { f_service_ << indent() << extends - << ".Client.__init__(self, transport, oprot_factory)" << endl; + << ".Client.__init__(self, transport, oprot_factory)" << '\n'; } else if (gen_tornado_) { f_service_ << indent() << extends - << ".Client.__init__(self, transport, iprot_factory, oprot_factory)" << endl; + << ".Client.__init__(self, transport, iprot_factory, oprot_factory)" << '\n'; } else { - f_service_ << indent() << extends << ".Client.__init__(self, iprot, oprot)" << endl; + f_service_ << indent() << extends << ".Client.__init__(self, iprot, oprot)" << '\n'; } } indent_down(); if (gen_tornado_ && extends.empty()) { - f_service_ << endl << - indent() << "@gen.engine" << endl << - indent() << "def _start_receiving(self):" << endl; + f_service_ << '\n' << + indent() << "@gen.coroutine" << '\n' << + indent() << "def _start_receiving(self):" << '\n'; indent_up(); - indent(f_service_) << "while True:" << endl; + indent(f_service_) << "while True:" << '\n'; indent_up(); - f_service_ << indent() << "try:" << endl - << indent() << indent_str() << "frame = yield self._transport.readFrame()" << endl - << indent() << "except TTransport.TTransportException as e:" << endl - << indent() << indent_str() << "for future in self._reqs.values():" << endl - << indent() << indent_str() << indent_str() << "future.set_exception(e)" << endl - << indent() << indent_str() << "self._reqs = {}" << endl - << indent() << indent_str() << "return" << endl - << indent() << "tr = TTransport.TMemoryBuffer(frame)" << endl - << indent() << "iprot = self._iprot_factory.getProtocol(tr)" << endl - << indent() << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << endl - << indent() << "method = getattr(self, 'recv_' + fname)" << endl - << indent() << "future = self._reqs.pop(rseqid, None)" << endl - << indent() << "if not future:" << endl - << indent() << indent_str() << "# future has already been discarded" << endl - << indent() << indent_str() << "continue" << endl - << indent() << "try:" << endl - << indent() << indent_str() << "result = method(iprot, mtype, rseqid)" << endl - << indent() << "except Exception as e:" << endl - << indent() << indent_str() << "future.set_exception(e)" << endl - << indent() << "else:" << endl - << indent() << indent_str() << "future.set_result(result)" << endl; + f_service_ << indent() << "try:" << '\n' + << indent() << indent_str() << "frame = yield self._transport.readFrame()" << '\n' + << indent() << "except TTransport.TTransportException as e:" << '\n' + << indent() << indent_str() << "for future in self._reqs.values():" << '\n' + << indent() << indent_str() << indent_str() << "future.set_exception(e)" << '\n' + << indent() << indent_str() << "self._reqs = {}" << '\n' + << indent() << indent_str() << "return" << '\n' + << indent() << "tr = TTransport.TMemoryBuffer(frame)" << '\n' + << indent() << "iprot = self._iprot_factory.getProtocol(tr)" << '\n' + << indent() << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n' + << indent() << "method = getattr(self, 'recv_' + fname)" << '\n' + << indent() << "future = self._reqs.pop(rseqid, None)" << '\n' + << indent() << "if not future:" << '\n' + << indent() << indent_str() << "# future has already been discarded" << '\n' + << indent() << indent_str() << "continue" << '\n' + << indent() << "try:" << '\n' + << indent() << indent_str() << "result = method(iprot, mtype, rseqid)" << '\n' + << indent() << "except Exception as e:" << '\n' + << indent() << indent_str() << "future.set_exception(e)" << '\n' + << indent() << "else:" << '\n' + << indent() << indent_str() << "future.set_result(result)" << '\n'; indent_down(); indent_down(); } @@ -1473,20 +1503,20 @@ void t_py_generator::generate_service_client(t_service* tservice) { vector::const_iterator fld_iter; string funname = (*f_iter)->get_name(); - f_service_ << endl; + f_service_ << '\n'; // Open function - indent(f_service_) << "def " << function_signature(*f_iter, false) << ":" << endl; + indent(f_service_) << "def " << function_signature(*f_iter, false) << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, (*f_iter)); if (gen_twisted_) { - indent(f_service_) << "seqid = self._seqid = self._seqid + 1" << endl; - indent(f_service_) << "self._reqs[seqid] = defer.Deferred()" << endl << endl; + indent(f_service_) << "seqid = self._seqid = self._seqid + 1" << '\n'; + indent(f_service_) << "self._reqs[seqid] = defer.Deferred()" << '\n' << '\n'; indent(f_service_) << "d = defer.maybeDeferred(self.send_" << funname; } else if (gen_tornado_) { - indent(f_service_) << "self._seqid += 1" << endl; + indent(f_service_) << "self._seqid += 1" << '\n'; if (!(*f_iter)->is_oneway()) { - indent(f_service_) << "future = self._reqs[self._seqid] = concurrent.Future()" << endl; + indent(f_service_) << "future = self._reqs[self._seqid] = concurrent.Future()" << '\n'; } indent(f_service_) << "self.send_" << funname << "("; @@ -1509,19 +1539,19 @@ void t_py_generator::generate_service_client(t_service* tservice) { f_service_ << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!(*f_iter)->is_oneway()) { if (gen_twisted_) { // nothing. See the next block. } else if (gen_tornado_) { - indent(f_service_) << "return future" << endl; + indent(f_service_) << "return future" << '\n'; } else { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "self.recv_" << funname << "()" << endl; + f_service_ << "self.recv_" << funname << "()" << '\n'; } } indent_down(); @@ -1529,40 +1559,40 @@ void t_py_generator::generate_service_client(t_service* tservice) { if (gen_twisted_) { // This block injects the body of the send_<> method for twisted (and a cb/eb pair) indent_up(); - indent(f_service_) << "d.addCallbacks(" << endl; + indent(f_service_) << "d.addCallbacks(" << '\n'; indent_up(); - f_service_ << indent() << "callback=self.cb_send_" << funname << "," << endl << indent() - << "callbackArgs=(seqid,)," << endl << indent() << "errback=self.eb_send_" - << funname << "," << endl << indent() << "errbackArgs=(seqid,))" << endl; + f_service_ << indent() << "callback=self.cb_send_" << funname << "," << '\n' << indent() + << "callbackArgs=(seqid,)," << '\n' << indent() << "errback=self.eb_send_" + << funname << "," << '\n' << indent() << "errbackArgs=(seqid,))" << '\n'; indent_down(); - indent(f_service_) << "return d" << endl; + indent(f_service_) << "return d" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "def cb_send_" << funname << "(self, _, seqid):" << endl; + indent(f_service_) << "def cb_send_" << funname << "(self, _, seqid):" << '\n'; indent_up(); if ((*f_iter)->is_oneway()) { // if one-way, fire the deferred & remove it from _reqs - f_service_ << indent() << "d = self._reqs.pop(seqid)" << endl << indent() - << "d.callback(None)" << endl << indent() << "return d" << endl; + f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent() + << "d.callback(None)" << '\n' << indent() << "return d" << '\n'; } else { - f_service_ << indent() << "return self._reqs[seqid]" << endl; + f_service_ << indent() << "return self._reqs[seqid]" << '\n'; } indent_down(); - f_service_ << endl; + f_service_ << '\n'; // add an errback to fail the request if the call to send_<> raised an exception - indent(f_service_) << "def eb_send_" << funname << "(self, f, seqid):" << endl; + indent(f_service_) << "def eb_send_" << funname << "(self, f, seqid):" << '\n'; indent_up(); - f_service_ << indent() << "d = self._reqs.pop(seqid)" << endl << indent() << "d.errback(f)" - << endl << indent() << "return d" << endl; + f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent() << "d.errback(f)" + << '\n' << indent() << "return d" << '\n'; indent_down(); } - f_service_ << endl; - indent(f_service_) << "def send_" << function_signature(*f_iter, false) << ":" << endl; + f_service_ << '\n'; + indent(f_service_) << "def send_" << function_signature(*f_iter, false, true) << ":" << '\n'; indent_up(); std::string argsname = (*f_iter)->get_name() + "_args"; @@ -1570,29 +1600,29 @@ void t_py_generator::generate_service_client(t_service* tservice) { // Serialize the request header if (gen_twisted_ || gen_tornado_) { - f_service_ << indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << endl + f_service_ << indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << '\n' << indent() << "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " - << messageType << ", self._seqid)" << endl; + << messageType << ", self._seqid)" << '\n'; } else { f_service_ << indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " - << messageType << ", self._seqid)" << endl; + << messageType << ", self._seqid)" << '\n'; } - f_service_ << indent() << "args = " << argsname << "()" << endl; + f_service_ << indent() << "args = " << argsname << "()" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = " - << (*fld_iter)->get_name() << endl; + << (*fld_iter)->get_name() << '\n'; } // Write to the stream if (gen_twisted_ || gen_tornado_) { - f_service_ << indent() << "args.write(oprot)" << endl << indent() << "oprot.writeMessageEnd()" - << endl << indent() << "oprot.trans.flush()" << endl; + f_service_ << indent() << "args.write(oprot)" << '\n' << indent() << "oprot.writeMessageEnd()" + << '\n' << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "args.write(self._oprot)" << endl << indent() - << "self._oprot.writeMessageEnd()" << endl << indent() - << "self._oprot.trans.flush()" << endl; + f_service_ << indent() << "args.write(self._oprot)" << '\n' << indent() + << "self._oprot.writeMessageEnd()" << '\n' << indent() + << "self._oprot.trans.flush()" << '\n'; } indent_down(); @@ -1600,51 +1630,51 @@ void t_py_generator::generate_service_client(t_service* tservice) { if (!(*f_iter)->is_oneway()) { std::string resultname = (*f_iter)->get_name() + "_result"; // Open function - f_service_ << endl; + f_service_ << '\n'; if (gen_twisted_ || gen_tornado_) { f_service_ << indent() << "def recv_" << (*f_iter)->get_name() - << "(self, iprot, mtype, rseqid):" << endl; + << "(self, iprot, mtype, rseqid):" << '\n'; } else { t_struct noargs(program_); t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &noargs); - f_service_ << indent() << "def " << function_signature(&recv_function) << ":" << endl; + f_service_ << indent() << "def " << function_signature(&recv_function) << ":" << '\n'; } indent_up(); // TODO(mcslee): Validate message reply here, seq ids etc. if (gen_twisted_) { - f_service_ << indent() << "d = self._reqs.pop(rseqid)" << endl; + f_service_ << indent() << "d = self._reqs.pop(rseqid)" << '\n'; } else if (gen_tornado_) { } else { - f_service_ << indent() << "iprot = self._iprot" << endl << indent() - << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << endl; + f_service_ << indent() << "iprot = self._iprot" << '\n' << indent() + << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n'; } - f_service_ << indent() << "if mtype == TMessageType.EXCEPTION:" << endl - << indent() << indent_str() << "x = TApplicationException()" << endl; + f_service_ << indent() << "if mtype == TMessageType.EXCEPTION:" << '\n' + << indent() << indent_str() << "x = TApplicationException()" << '\n'; if (gen_twisted_) { - f_service_ << indent() << indent_str() << "x.read(iprot)" << endl << indent() - << indent_str() << "iprot.readMessageEnd()" << endl << indent() << indent_str() << "return d.errback(x)" - << endl << indent() << "result = " << resultname << "()" << endl << indent() - << "result.read(iprot)" << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent() + << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "return d.errback(x)" + << '\n' << indent() << "result = " << resultname << "()" << '\n' << indent() + << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; } else { - f_service_ << indent() << indent_str() << "x.read(iprot)" << endl << indent() - << indent_str() << "iprot.readMessageEnd()" << endl << indent() << indent_str() << "raise x" << endl - << indent() << "result = " << resultname << "()" << endl << indent() - << "result.read(iprot)" << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent() + << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "raise x" << '\n' + << indent() << "result = " << resultname << "()" << '\n' << indent() + << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; } // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if result.success is not None:" << endl; + f_service_ << indent() << "if result.success is not None:" << '\n'; if (gen_twisted_) { - f_service_ << indent() << indent_str() << "return d.callback(result.success)" << endl; + f_service_ << indent() << indent_str() << "return d.callback(result.success)" << '\n'; } else { - f_service_ << indent() << indent_str() << "return result.success" << endl; + f_service_ << indent() << indent_str() << "return result.success" << '\n'; } } @@ -1653,32 +1683,32 @@ void t_py_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); - f_service_ << indent() << "if result." << xname << " is not None:" << endl; + f_service_ << indent() << "if result." << xname << " is not None:" << '\n'; if (gen_twisted_) { f_service_ << indent() << indent_str() << "return d.errback(result." << xname << ")" - << endl; + << '\n'; } else { - f_service_ << indent() << indent_str() << "raise result." << xname << "" << endl; + f_service_ << indent() << indent_str() << "raise result." << xname << "" << '\n'; } } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { if (gen_twisted_) { - f_service_ << indent() << "return d.callback(None)" << endl; + f_service_ << indent() << "return d.callback(None)" << '\n'; } else { - f_service_ << indent() << "return" << endl; + f_service_ << indent() << "return" << '\n'; } } else { if (gen_twisted_) { f_service_ << indent() << "return d.errback(TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\"))" << endl; + << (*f_iter)->get_name() << " failed: unknown result\"))" << '\n'; } else { f_service_ << indent() << "raise TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\")" << endl; + << (*f_iter)->get_name() << " failed: unknown result\")" << '\n'; } } @@ -1711,29 +1741,27 @@ void t_py_generator::generate_service_remote(t_service* tservice) { f_remote.open(f_remote_name.c_str()); f_remote << - "#!/usr/bin/env python" << endl << - py_autogen_comment() << endl << - "import sys" << endl << - "import pprint" << endl << - "if sys.version_info[0] > 2:" << endl << - indent_str() << "from urllib.parse import urlparse" << endl << - "else:" << endl << - indent_str() << "from urlparse import urlparse" << endl << - "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << endl << - "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << endl << - endl; + "#!/usr/bin/env python" << '\n' << + py_autogen_comment() << '\n' << + "import sys" << '\n' << + "import pprint" << '\n' << + "if sys.version_info[0] > 2:" << '\n' << + indent_str() << "from urllib.parse import urlparse" << '\n' << + "else:" << '\n' << + indent_str() << "from urlparse import urlparse" << '\n' << + "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n' << + "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n' << '\n'; f_remote << - "from " << module_ << " import " << service_name_ << endl << - "from " << module_ << ".ttypes import *" << endl << - endl; + "from " << module_ << " import " << service_name_ << '\n' << + "from " << module_ << ".ttypes import *" << '\n' << '\n'; f_remote << - "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << endl << - indent_str() << "print('')" << endl << - indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << endl << - indent_str() << "print('')" << endl << - indent_str() << "print('Functions:')" << endl; + "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n' << + indent_str() << "print('')" << '\n' << + indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << '\n' << + indent_str() << "print('')" << '\n' << + indent_str() << "print('Functions:')" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_remote << indent_str() << "print(' " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "("; @@ -1749,88 +1777,88 @@ void t_py_generator::generate_service_remote(t_service* tservice) { } f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name(); } - f_remote << ")')" << endl; - } - f_remote << indent_str() << "print('')" << endl << indent_str() << "sys.exit(0)" << endl << endl; - - f_remote << "pp = pprint.PrettyPrinter(indent=2)" << endl - << "host = 'localhost'" << endl - << "port = 9090" << endl - << "uri = ''" << endl - << "framed = False" << endl - << "ssl = False" << endl - << "validate = True" << endl - << "ca_certs = None" << endl - << "keyfile = None" << endl - << "certfile = None" << endl - << "http = False" << endl - << "argi = 1" << endl - << endl - << "if sys.argv[argi] == '-h':" << endl - << indent_str() << "parts = sys.argv[argi + 1].split(':')" << endl - << indent_str() << "host = parts[0]" << endl - << indent_str() << "if len(parts) > 1:" << endl - << indent_str() << indent_str() << "port = int(parts[1])" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-u':" << endl - << indent_str() << "url = urlparse(sys.argv[argi + 1])" << endl - << indent_str() << "parts = url[1].split(':')" << endl - << indent_str() << "host = parts[0]" << endl - << indent_str() << "if len(parts) > 1:" << endl - << indent_str() << indent_str() << "port = int(parts[1])" << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "port = 80" << endl - << indent_str() << "uri = url[2]" << endl - << indent_str() << "if url[4]:" << endl - << indent_str() << indent_str() << "uri += '?%s' % url[4]" << endl - << indent_str() << "http = True" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << endl - << indent_str() << "framed = True" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << endl - << indent_str() << "ssl = True" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-novalidate':" << endl - << indent_str() << "validate = False" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-ca_certs':" << endl - << indent_str() << "ca_certs = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-keyfile':" << endl - << indent_str() << "keyfile = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-certfile':" << endl - << indent_str() << "certfile = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "cmd = sys.argv[argi]" << endl - << "args = sys.argv[argi + 1:]" << endl - << endl - << "if http:" << endl - << indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << endl - << "else:" << endl - << indent_str() << "if ssl:" << endl + f_remote << ")')" << '\n'; + } + f_remote << indent_str() << "print('')" << '\n' << indent_str() << "sys.exit(0)" << '\n' << '\n'; + + f_remote << "pp = pprint.PrettyPrinter(indent=2)" << '\n' + << "host = 'localhost'" << '\n' + << "port = 9090" << '\n' + << "uri = ''" << '\n' + << "framed = False" << '\n' + << "ssl = False" << '\n' + << "validate = True" << '\n' + << "ca_certs = None" << '\n' + << "keyfile = None" << '\n' + << "certfile = None" << '\n' + << "http = False" << '\n' + << "argi = 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-h':" << '\n' + << indent_str() << "parts = sys.argv[argi + 1].split(':')" << '\n' + << indent_str() << "host = parts[0]" << '\n' + << indent_str() << "if len(parts) > 1:" << '\n' + << indent_str() << indent_str() << "port = int(parts[1])" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-u':" << '\n' + << indent_str() << "url = urlparse(sys.argv[argi + 1])" << '\n' + << indent_str() << "parts = url[1].split(':')" << '\n' + << indent_str() << "host = parts[0]" << '\n' + << indent_str() << "if len(parts) > 1:" << '\n' + << indent_str() << indent_str() << "port = int(parts[1])" << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "port = 80" << '\n' + << indent_str() << "uri = url[2]" << '\n' + << indent_str() << "if url[4]:" << '\n' + << indent_str() << indent_str() << "uri += '?%s' % url[4]" << '\n' + << indent_str() << "http = True" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << '\n' + << indent_str() << "framed = True" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << '\n' + << indent_str() << "ssl = True" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-novalidate':" << '\n' + << indent_str() << "validate = False" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-ca_certs':" << '\n' + << indent_str() << "ca_certs = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-keyfile':" << '\n' + << indent_str() << "keyfile = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-certfile':" << '\n' + << indent_str() << "certfile = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "cmd = sys.argv[argi]" << '\n' + << "args = sys.argv[argi + 1:]" << '\n' + << '\n' + << "if http:" << '\n' + << indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << '\n' + << "else:" << '\n' + << indent_str() << "if ssl:" << '\n' << indent_str() << indent_str() << "socket = TSSLSocket.TSSLSocket(host, port, " "validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)" - << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << endl - << indent_str() << "if framed:" << endl - << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << endl - << "protocol = TBinaryProtocol(transport)" << endl - << "client = " << service_name_ << ".Client(protocol)" << endl - << "transport.open()" << endl - << endl; + << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << '\n' + << indent_str() << "if framed:" << '\n' + << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << '\n' + << "protocol = TBinaryProtocol(transport)" << '\n' + << "client = " << service_name_ << ".Client(protocol)" << '\n' + << "transport.open()" << '\n' + << '\n'; // Generate the dispatch methods bool first = true; @@ -1846,12 +1874,12 @@ void t_py_generator::generate_service_remote(t_service* tservice) { const std::vector& args = arg_struct->get_members(); std::vector::size_type num_args = args.size(); - f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << endl; + f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << '\n'; indent_up(); - f_remote << indent() << "if len(args) != " << num_args << ":" << endl + f_remote << indent() << "if len(args) != " << num_args << ":" << '\n' << indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires " << num_args - << " args')" << endl - << indent() << indent_str() << "sys.exit(1)" << endl + << " args')" << '\n' + << indent() << indent_str() << "sys.exit(1)" << '\n' << indent() << "pp.pprint(client." << (*f_iter)->get_name() << "("; indent_down(); bool first_arg = true; @@ -1860,25 +1888,27 @@ void t_py_generator::generate_service_remote(t_service* tservice) { first_arg = false; else f_remote << " "; - if (args[i]->get_type()->is_string()) { + if (args[i]->get_type()->is_binary()) { + f_remote << "args[" << i << "].encode('utf-8'),"; + } else if (args[i]->get_type()->is_string()) { f_remote << "args[" << i << "],"; } else { f_remote << "eval(args[" << i << "]),"; } } - f_remote << "))" << endl; + f_remote << "))" << '\n'; - f_remote << endl; + f_remote << '\n'; } if (functions.size() > 0) { - f_remote << "else:" << endl; - f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << endl; - f_remote << indent_str() << "sys.exit(1)" << endl; - f_remote << endl; + f_remote << "else:" << '\n'; + f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << '\n'; + f_remote << indent_str() << "sys.exit(1)" << '\n'; + f_remote << '\n'; } - f_remote << "transport.close()" << endl; + f_remote << "transport.close()" << '\n'; // Close service file f_remote.close(); @@ -1913,100 +1943,100 @@ void t_py_generator::generate_service_server(t_service* tservice) { extends_processor = extends + ".Processor, "; } - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; // Generate the header portion if (gen_zope_interface_) { - f_service_ << "@implementer(Iface)" << endl - << "class Processor(" << extends_processor << "TProcessor):" << endl; + f_service_ << "@implementer(Iface)" << '\n' + << "class Processor(" << extends_processor << "TProcessor):" << '\n'; } else { - f_service_ << "class Processor(" << extends_processor << "Iface, TProcessor):" << endl; + f_service_ << "class Processor(" << extends_processor << "Iface, TProcessor):" << '\n'; } indent_up(); - indent(f_service_) << "def __init__(self, handler):" << endl; + indent(f_service_) << "def __init__(self, handler):" << '\n'; indent_up(); if (extends.empty()) { if (gen_zope_interface_) { - f_service_ << indent() << "self._handler = Iface(handler)" << endl; + f_service_ << indent() << "self._handler = Iface(handler)" << '\n'; } else { - f_service_ << indent() << "self._handler = handler" << endl; + f_service_ << indent() << "self._handler = handler" << '\n'; } - f_service_ << indent() << "self._processMap = {}" << endl; + f_service_ << indent() << "self._processMap = {}" << '\n'; } else { if (gen_zope_interface_) { - f_service_ << indent() << extends << ".Processor.__init__(self, Iface(handler))" << endl; + f_service_ << indent() << extends << ".Processor.__init__(self, Iface(handler))" << '\n'; } else { - f_service_ << indent() << extends << ".Processor.__init__(self, handler)" << endl; + f_service_ << indent() << extends << ".Processor.__init__(self, handler)" << '\n'; } } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "self._processMap[\"" << (*f_iter)->get_name() - << "\"] = Processor.process_" << (*f_iter)->get_name() << endl; + << "\"] = Processor.process_" << (*f_iter)->get_name() << '\n'; } - f_service_ << indent() << "self._on_message_begin = None" << endl; + f_service_ << indent() << "self._on_message_begin = None" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; - f_service_ << indent() << "def on_message_begin(self, func):" << endl; + f_service_ << indent() << "def on_message_begin(self, func):" << '\n'; indent_up(); - f_service_ << indent() << "self._on_message_begin = func" << endl; + f_service_ << indent() << "self._on_message_begin = func" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation - f_service_ << indent() << "def process(self, iprot, oprot):" << endl; + f_service_ << indent() << "def process(self, iprot, oprot):" << '\n'; indent_up(); - f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << endl; - f_service_ << indent() << "if self._on_message_begin:" << endl; + f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << '\n'; + f_service_ << indent() << "if self._on_message_begin:" << '\n'; indent_up(); - f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << endl; + f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << '\n'; indent_down(); // TODO(mcslee): validate message // HOT: dictionary function lookup - f_service_ << indent() << "if name not in self._processMap:" << endl; + f_service_ << indent() << "if name not in self._processMap:" << '\n'; indent_up(); - f_service_ << indent() << "iprot.skip(TType.STRUCT)" << endl - << indent() << "iprot.readMessageEnd()" << endl + f_service_ << indent() << "iprot.skip(TType.STRUCT)" << '\n' + << indent() << "iprot.readMessageEnd()" << '\n' << indent() << "x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown " "function %s' % (name))" - << endl - << indent() << "oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)" << endl - << indent() << "x.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << '\n' + << indent() << "oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)" << '\n' + << indent() << "x.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; if (gen_twisted_) { - f_service_ << indent() << "return defer.succeed(None)" << endl; + f_service_ << indent() << "return defer.succeed(None)" << '\n'; } else { - f_service_ << indent() << "return" << endl; + f_service_ << indent() << "return" << '\n'; } indent_down(); - f_service_ << indent() << "else:" << endl; + f_service_ << indent() << "else:" << '\n'; if (gen_twisted_ || gen_tornado_) { f_service_ << indent() << indent_str() - << "return self._processMap[name](self, seqid, iprot, oprot)" << endl; + << "return self._processMap[name](self, seqid, iprot, oprot)" << '\n'; } else { f_service_ << indent() << indent_str() << "self._processMap[name](self, seqid, iprot, oprot)" - << endl; + << '\n'; // Read end of args field, the T_STOP, and the struct close - f_service_ << indent() << "return True" << endl; + f_service_ << indent() << "return True" << '\n'; } indent_down(); // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << endl; + f_service_ << '\n'; generate_process_function(tservice, *f_iter); } @@ -2022,11 +2052,11 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* (void)tservice; // Open function if (gen_tornado_) { - f_service_ << indent() << "@gen.coroutine" << endl << indent() << "def process_" - << tfunction->get_name() << "(self, seqid, iprot, oprot):" << endl; + f_service_ << indent() << "@gen.coroutine" << '\n' << indent() << "def process_" + << tfunction->get_name() << "(self, seqid, iprot, oprot):" << '\n'; } else { f_service_ << indent() << "def process_" << tfunction->get_name() - << "(self, seqid, iprot, oprot):" << endl; + << "(self, seqid, iprot, oprot):" << '\n'; } indent_up(); @@ -2034,8 +2064,8 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; - f_service_ << indent() << "args = " << argsname << "()" << endl << indent() << "args.read(iprot)" - << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << "args = " << argsname << "()" << '\n' << indent() << "args.read(iprot)" + << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2043,7 +2073,7 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "result = " << resultname << "()" << endl; + f_service_ << indent() << "result = " << resultname << "()" << '\n'; } if (gen_twisted_) { @@ -2063,85 +2093,85 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (tfunction->is_oneway()) { f_service_ << indent() << "d.addErrback(self.handle_exception_" << tfunction->get_name() - << ", seqid)" << endl; + << ", seqid)" << '\n'; } else { f_service_ << indent() << "d.addCallback(self.write_results_success_" << tfunction->get_name() - << ", result, seqid, oprot)" << endl + << ", result, seqid, oprot)" << '\n' << indent() << "d.addErrback(self.write_results_exception_" - << tfunction->get_name() << ", result, seqid, oprot)" << endl; + << tfunction->get_name() << ", result, seqid, oprot)" << '\n'; } - f_service_ << indent() << "return d" << endl << endl; + f_service_ << indent() << "return d" << '\n' << '\n'; indent_down(); if (tfunction->is_oneway()) { indent(f_service_) << "def handle_exception_" << tfunction->get_name() - << "(self, error, seqid):" << endl; + << "(self, error, seqid):" << '\n'; } else { indent(f_service_) << "def write_results_success_" << tfunction->get_name() - << "(self, success, result, seqid, oprot):" << endl; + << "(self, success, result, seqid, oprot):" << '\n'; indent_up(); if (!tfunction->get_returntype()->is_void()) { - f_service_ << indent() << "result.success = success" << endl; + f_service_ << indent() << "result.success = success" << '\n'; } f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl - << endl; + << "\", TMessageType.REPLY, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n' + << '\n'; indent_down(); indent(f_service_) << "def write_results_exception_" << tfunction->get_name() - << "(self, error, result, seqid, oprot):" << endl; + << "(self, error, result, seqid, oprot):" << '\n'; } indent_up(); if (!tfunction->is_oneway()) { - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; } - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; // Kinda absurd - f_service_ << indent() << indent_str() << "error.raiseException()" << endl; + f_service_ << indent() << indent_str() << "error.raiseException()" << '\n'; if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl; + << ":" << '\n'; indent_up(); - f_service_ << indent() << "result." << xname << " = " << xname << endl; + f_service_ << indent() << "result." << xname << " = " << xname << '\n'; indent_down(); } } - f_service_ << indent() << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + f_service_ << indent() << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl + << '\n' << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl + f_service_ << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Exception in oneway handler')" << endl; + << "logging.exception('Exception in oneway handler')" << '\n'; } indent_down(); @@ -2152,9 +2182,9 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* vector::const_iterator f_iter; if (!tfunction->is_oneway()) { - indent(f_service_) << "msg_type = TMessageType.REPLY" << endl; + indent(f_service_) << "msg_type = TMessageType.REPLY" << '\n'; } - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; indent_up(); f_service_ << indent(); if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { @@ -2170,45 +2200,45 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << "))" << endl; + f_service_ << "))" << '\n'; indent_down(); if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl - << indent() << indent_str() << "result." << xname << " = " << xname << endl; + << ":" << '\n' + << indent() << indent_str() << "result." << xname << " = " << xname << '\n'; } } - f_service_ << indent() << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + f_service_ << indent() << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl; + << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl + f_service_ << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Exception in oneway handler')" << endl; + << "logging.exception('Exception in oneway handler')" << '\n'; } if (!tfunction->is_oneway()) { f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } // Close function @@ -2217,7 +2247,7 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } else { // py // Try block for a function with exceptions // It also catches arbitrary exceptions raised by handler method to propagate them to the client - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; indent_up(); // Generate the function call @@ -2239,48 +2269,48 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; } indent_down(); f_service_ << indent() - << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl; + << ":" << '\n'; indent_up(); - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; - f_service_ << indent() << "result." << xname << " = " << xname << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; + f_service_ << indent() << "result." << xname << " = " << xname << '\n'; indent_down(); } - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl + << '\n' << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl - << indent() << indent_str() << "logging.exception('Exception in oneway handler')" << endl; + f_service_ << indent() << "except Exception:" << '\n' + << indent() << indent_str() << "logging.exception('Exception in oneway handler')" << '\n'; } // Close function @@ -2341,18 +2371,21 @@ void t_py_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_DOUBLE: out << "readDouble()"; break; + case t_base_type::TYPE_UUID: + out << "readUuid()"; + break; default: throw "compiler error: no Python name for base type " + t_base_type::t_base_name(tbase); } } - out << endl; + out << '\n'; } else if (type->is_enum()) { if (gen_enum_) { indent(out) << name << " = " << type_name(type) << "(iprot.readI32())"; } else { indent(out) << name << " = iprot.readI32()"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2365,10 +2398,10 @@ void t_py_generator::generate_deserialize_field(ostream& out, */ void t_py_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { if (is_immutable(tstruct)) { - out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << endl; + out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << '\n'; } else { - out << indent() << prefix << " = " << type_name(tstruct) << "()" << endl - << indent() << prefix << ".read(iprot)" << endl; + out << indent() << prefix << " = " << type_name(tstruct) << "()" << '\n' + << indent() << prefix << ".read(iprot)" << '\n'; } } @@ -2389,20 +2422,20 @@ void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Declare variables, read header if (ttype->is_map()) { - out << indent() << prefix << " = {}" << endl << indent() << "(" << ktype << ", " << vtype - << ", " << size << ") = iprot.readMapBegin()" << endl; + out << indent() << prefix << " = {}" << '\n' << indent() << "(" << ktype << ", " << vtype + << ", " << size << ") = iprot.readMapBegin()" << '\n'; } else if (ttype->is_set()) { - out << indent() << prefix << " = set()" << endl << indent() << "(" << etype << ", " << size - << ") = iprot.readSetBegin()" << endl; + out << indent() << prefix << " = set()" << '\n' << indent() << "(" << etype << ", " << size + << ") = iprot.readSetBegin()" << '\n'; } else if (ttype->is_list()) { - out << indent() << prefix << " = []" << endl << indent() << "(" << etype << ", " << size - << ") = iprot.readListBegin()" << endl; + out << indent() << prefix << " = []" << '\n' << indent() << "(" << etype << ", " << size + << ") = iprot.readListBegin()" << '\n'; } // For loop iterates over elements string i = tmp("_i"); indent(out) << - "for " << i << " in range(" << size << "):" << endl; + "for " << i << " in range(" << size << "):" << '\n'; indent_up(); @@ -2418,20 +2451,20 @@ void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd()" << endl; + indent(out) << "iprot.readMapEnd()" << '\n'; if (is_immutable(ttype)) { - indent(out) << prefix << " = TFrozenDict(" << prefix << ")" << endl; + indent(out) << prefix << " = TFrozenDict(" << prefix << ")" << '\n'; } } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd()" << endl; + indent(out) << "iprot.readSetEnd()" << '\n'; if (is_immutable(ttype)) { - indent(out) << prefix << " = frozenset(" << prefix << ")" << endl; + indent(out) << prefix << " = frozenset(" << prefix << ")" << '\n'; } } else if (ttype->is_list()) { if (is_immutable(ttype)) { - indent(out) << prefix << " = tuple(" << prefix << ")" << endl; + indent(out) << prefix << " = tuple(" << prefix << ")" << '\n'; } - indent(out) << "iprot.readListEnd()" << endl; + indent(out) << "iprot.readListEnd()" << '\n'; } } @@ -2447,7 +2480,7 @@ void t_py_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } /** @@ -2459,7 +2492,7 @@ void t_py_generator::generate_deserialize_set_element(ostream& out, t_set* tset, generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ")" << endl; + indent(out) << prefix << ".add(" << elem << ")" << '\n'; } /** @@ -2473,7 +2506,7 @@ void t_py_generator::generate_deserialize_list_element(ostream& out, generate_deserialize_field(out, &felem); - indent(out) << prefix << ".append(" << elem << ")" << endl; + indent(out) << prefix << ".append(" << elem << ")" << '\n'; } /** @@ -2533,6 +2566,9 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str case t_base_type::TYPE_DOUBLE: out << "writeDouble(" << name << ")"; break; + case t_base_type::TYPE_UUID: + out << "writeUuid(" << name << ")"; + break; default: throw "compiler error: no Python name for base type " + t_base_type::t_base_name(tbase); } @@ -2543,7 +2579,7 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str out << "writeI32(" << name << ")"; } } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2560,50 +2596,50 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str */ void t_py_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(oprot)" << endl; + indent(out) << prefix << ".write(oprot)" << '\n'; } void t_py_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) { if (ttype->is_map()) { indent(out) << "oprot.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - indent(out) << "for " << kiter << ", " << viter << " in " << prefix << ".items():" << endl; + indent(out) << "for " << kiter << ", " << viter << " in " << prefix << ".items():" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for " << iter << " in " << prefix << ":" << endl; + indent(out) << "for " << iter << " in " << prefix << ":" << '\n'; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for " << iter << " in " << prefix << ":" << endl; + indent(out) << "for " << iter << " in " << prefix << ":" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); } if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd()" << endl; + indent(out) << "oprot.writeMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd()" << endl; + indent(out) << "oprot.writeSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd()" << endl; + indent(out) << "oprot.writeListEnd()" << '\n'; } } @@ -2669,7 +2705,7 @@ void t_py_generator::generate_python_docstring(ostream& out, const vector& fields = tstruct->get_members(); if (fields.size() > 0) { if (has_doc) { - ss << endl; + ss << '\n'; } has_doc = true; ss << subheader << ":\n"; @@ -2680,7 +2716,7 @@ void t_py_generator::generate_python_docstring(ostream& out, if (p->has_doc()) { ss << ": " << p->get_doc(); } else { - ss << endl; + ss << '\n'; } } } @@ -2706,7 +2742,10 @@ void t_py_generator::generate_python_docstring(ostream& out, t_doc* tdoc) { */ string t_py_generator::declare_argument(t_field* tfield) { std::ostringstream result; - result << tfield->get_name() << "="; + t_field::e_req req = tfield->get_req(); + result << tfield->get_name() << member_hint(tfield->get_type(), req); + + result << " = "; if (tfield->get_value() != nullptr) { result << render_field_default_value(tfield); } else { @@ -2735,7 +2774,7 @@ string t_py_generator::render_field_default_value(t_field* tfield) { * @param tfunction Function definition * @return String of rendered function definition */ -string t_py_generator::function_signature(t_function* tfunction, bool interface) { +string t_py_generator::function_signature(t_function* tfunction, bool interface, bool send_part) { vector pre; vector post; string signature = tfunction->get_name() + "("; @@ -2745,6 +2784,10 @@ string t_py_generator::function_signature(t_function* tfunction, bool interface) } signature += argument_list(tfunction->get_arglist(), &pre, &post) + ")"; + if (!send_part) { + signature += func_hint(tfunction->get_returntype()); + } + return signature; } @@ -2775,6 +2818,7 @@ string t_py_generator::argument_list(t_struct* tstruct, vector* pre, vec result += ", "; } result += (*f_iter)->get_name(); + result += arg_hint((*f_iter)->get_type()); } if (post) { for (s_iter = post->begin(); s_iter != post->end(); ++s_iter) { @@ -2804,8 +2848,78 @@ string t_py_generator::type_name(t_type* ttype) { return ttype->get_name(); } +string t_py_generator::arg_hint(t_type* type) { + if (gen_type_hints_) { + return ": " + type_to_py_type(type); + } + + return ""; +} + +string t_py_generator::member_hint(t_type* type, t_field::e_req req) { + if (gen_type_hints_) { + if (req != t_field::T_REQUIRED) { + return ": typing.Optional[" + type_to_py_type(type) + "]"; + } else { + return ": " + type_to_py_type(type); + } + } + + return ""; +} + +string t_py_generator::func_hint(t_type* type) { + if (gen_type_hints_) { + return " -> " + type_to_py_type(type); + } + + return ""; +} + /** - * Converts the parse type to a Python tyoe + * Converts the parse type to a Python type + */ +string t_py_generator::type_to_py_type(t_type* type) { + type = get_true_type(type); + + if (type->is_binary()) { + return "bytes"; + } + if (type->is_base_type()) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + switch (tbase) { + case t_base_type::TYPE_VOID: + return "None"; + case t_base_type::TYPE_STRING: + return "str"; + case t_base_type::TYPE_BOOL: + return "bool"; + case t_base_type::TYPE_I8: + case t_base_type::TYPE_I16: + case t_base_type::TYPE_I32: + case t_base_type::TYPE_I64: + return "int"; + case t_base_type::TYPE_DOUBLE: + return "float"; + case t_base_type::TYPE_UUID: + return "UUID"; + } + } else if (type->is_enum() || type->is_struct() || type->is_xception()) { + return type_name(type); + } else if (type->is_map()) { + return "dict[" + type_to_py_type(((t_map*)type)->get_key_type()) + ", " + + type_to_py_type(((t_map*)type)->get_val_type()) + "]"; + } else if (type->is_set()) { + return "set[" + type_to_py_type(((t_set*)type)->get_elem_type()) + "]"; + } else if (type->is_list()) { + return "list[" + type_to_py_type(((t_list*)type)->get_elem_type()) + "]"; + } + + throw "INVALID TYPE IN type_to_py_type: " + type->get_name(); +} + +/** + * Converts the parse type to a Python type enum */ string t_py_generator::type_to_enum(t_type* type) { type = get_true_type(type); @@ -2829,6 +2943,8 @@ string t_py_generator::type_to_enum(t_type* type) { return "TType.I64"; case t_base_type::TYPE_DOUBLE: return "TType.DOUBLE"; + case t_base_type::TYPE_UUID: + return "TType.UUID"; default: throw "compiler error: unhandled type"; } @@ -2887,7 +3003,6 @@ std::string t_py_generator::display_name() const { return "Python"; } - THRIFT_REGISTER_GENERATOR( py, "Python", @@ -2908,4 +3023,5 @@ THRIFT_REGISTER_GENERATOR( " Package prefix for generated files.\n" " old_style: Deprecated. Generate old-style classes.\n" " enum: Generates Python's IntEnum, connects thrift to python enums. Python 3.4 and higher.\n" + " type_hints: Generate type hints and type checks in write method. Requires the enum option.\n" ) diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc index 17e57cf95df..e9465736692 100644 --- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc @@ -43,8 +43,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * A subclass of std::ofstream that includes indenting functionality. */ @@ -283,11 +281,11 @@ void t_rb_generator::init_generator() { f_consts_.open(f_consts_name.c_str()); // Print header - f_types_ << rb_autogen_comment() << endl << render_require_thrift() << render_includes() << endl; + f_types_ << rb_autogen_comment() << '\n' << render_require_thrift() << render_includes() << '\n'; begin_namespace(f_types_, ruby_modules(program_)); - f_consts_ << rb_autogen_comment() << endl << render_require_thrift() << "require '" - << require_prefix_ << underscore(program_name_) << "_types'" << endl << endl; + f_consts_ << rb_autogen_comment() << '\n' << render_require_thrift() << "require '" + << require_prefix_ << underscore(program_name_) << "_types'" << '\n' << '\n'; begin_namespace(f_consts_, ruby_modules(program_)); } @@ -360,7 +358,7 @@ void t_rb_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_rb_generator::generate_enum(t_enum* tenum) { - f_types_.indent() << "module " << capitalize(tenum->get_name()) << endl; + f_types_.indent() << "module " << capitalize(tenum->get_name()) << '\n'; f_types_.indent_up(); vector constants = tenum->get_constants(); @@ -374,7 +372,7 @@ void t_rb_generator::generate_enum(t_enum* tenum) { string name = capitalize((*c_iter)->get_name()); generate_rdoc(f_types_, *c_iter); - f_types_.indent() << name << " = " << value << endl; + f_types_.indent() << name << " = " << value << '\n'; } // Create a hash mapping values back to their names (as strings) since ruby has no native enum @@ -387,7 +385,7 @@ void t_rb_generator::generate_enum(t_enum* tenum) { f_types_ << ", "; f_types_ << value << " => \"" << capitalize((*c_iter)->get_name()) << "\""; } - f_types_ << "}" << endl; + f_types_ << "}" << '\n'; // Create a set with valid values for this enum f_types_.indent() << "VALID_VALUES = Set.new(["; @@ -397,10 +395,10 @@ void t_rb_generator::generate_enum(t_enum* tenum) { f_types_ << ", "; f_types_ << capitalize((*c_iter)->get_name()); } - f_types_ << "]).freeze" << endl; + f_types_ << "]).freeze" << '\n'; f_types_.indent_down(); - f_types_.indent() << "end" << endl << endl; + f_types_.indent() << "end" << '\n' << '\n'; } /** @@ -414,7 +412,7 @@ void t_rb_generator::generate_const(t_const* tconst) { name[0] = toupper(name[0]); f_consts_.indent() << name << " = "; - render_const_value(f_consts_, type, value) << endl << endl; + render_const_value(f_consts_, type, value) << '\n' << '\n'; } /** @@ -454,7 +452,7 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, } else if (type->is_enum()) { out.indent() << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << full_type_name(type) << ".new({" << endl; + out << full_type_name(type) << ".new({" << '\n'; out.indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -472,21 +470,21 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, } out.indent(); render_const_value(out, g_type_string, v_iter->first) << " => "; - render_const_value(out, field_type, v_iter->second) << "," << endl; + render_const_value(out, field_type, v_iter->second) << "," << '\n'; } out.indent_down(); out.indent() << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; out.indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out.indent(); render_const_value(out, ktype, v_iter->first) << " => "; - render_const_value(out, vtype, v_iter->second) << "," << endl; + render_const_value(out, vtype, v_iter->second) << "," << '\n'; } out.indent_down(); out.indent() << "}"; @@ -498,16 +496,16 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "Set.new([" << endl; + out << "Set.new([" << '\n'; } else { - out << "[" << endl; + out << "[" << '\n'; } out.indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out.indent(); - render_const_value(out, etype, *v_iter) << "," << endl; + render_const_value(out, etype, *v_iter) << "," << '\n'; } out.indent_down(); if (type->is_set()) { @@ -552,7 +550,7 @@ void t_rb_generator::generate_rb_struct_declaration(t_rb_ofstream& out, t_struct if (is_exception) { out << " < ::Thrift::Exception"; } - out << "; end" << endl << endl; + out << "; end" << '\n' << '\n'; } /** @@ -576,10 +574,10 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, if (is_exception) { out << " < ::Thrift::Exception"; } - out << endl; + out << '\n'; out.indent_up(); - out.indent() << "include ::Thrift::Struct, ::Thrift::Struct_Union" << endl; + out.indent() << "include ::Thrift::Struct, ::Thrift::Struct_Union" << '\n'; if (is_exception) { generate_rb_simple_exception_constructor(out, tstruct); @@ -589,10 +587,10 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, generate_field_defns(out, tstruct); generate_rb_struct_required_validator(out, tstruct); - out.indent() << "::Thrift::Struct.generate_accessors self" << endl; + out.indent() << "::Thrift::Struct.generate_accessors self" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } /** @@ -603,10 +601,10 @@ void t_rb_generator::generate_rb_union(t_rb_ofstream& out, bool is_exception = false) { (void)is_exception; generate_rdoc(out, tstruct); - out.indent() << "class " << type_name(tstruct) << " < ::Thrift::Union" << endl; + out.indent() << "class " << type_name(tstruct) << " < ::Thrift::Union" << '\n'; out.indent_up(); - out.indent() << "include ::Thrift::Struct_Union" << endl; + out.indent() << "include ::Thrift::Struct_Union" << '\n'; generate_field_constructors(out, tstruct); @@ -614,15 +612,15 @@ void t_rb_generator::generate_rb_union(t_rb_ofstream& out, generate_field_defns(out, tstruct); generate_rb_union_validator(out, tstruct); - out.indent() << "::Thrift::Union.generate_accessors self" << endl; + out.indent() << "::Thrift::Union.generate_accessors self" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } void t_rb_generator::generate_field_constructors(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "class << self" << endl; + out.indent() << "class << self" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -630,19 +628,19 @@ void t_rb_generator::generate_field_constructors(t_rb_ofstream& out, t_struct* t for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (f_iter != fields.begin()) { - out << endl; + out << '\n'; } std::string field_name = (*f_iter)->get_name(); - out.indent() << "def " << field_name << "(val)" << endl; - out.indent() << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << endl; - out.indent() << "end" << endl; + out.indent() << "def " << field_name << "(val)" << '\n'; + out.indent() << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << '\n'; + out.indent() << "end" << '\n'; } out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; - out << endl; + out << '\n'; } void t_rb_generator::generate_rb_simple_exception_constructor(t_rb_ofstream& out, @@ -655,15 +653,15 @@ void t_rb_generator::generate_rb_simple_exception_constructor(t_rb_ofstream& out if ((*m_iter)->get_type()->is_string()) { string name = (*m_iter)->get_name(); - out.indent() << "def initialize(message=nil)" << endl; + out.indent() << "def initialize(message=nil)" << '\n'; out.indent_up(); - out.indent() << "super()" << endl; - out.indent() << "self." << name << " = message" << endl; + out.indent() << "super()" << '\n'; + out.indent() << "self." << name << " = message" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; if (name != "message") { - out.indent() << "def message; " << name << " end" << endl << endl; + out.indent() << "def message; " << name << " end" << '\n' << '\n'; } } } @@ -677,20 +675,20 @@ void t_rb_generator::generate_field_constants(t_rb_ofstream& out, t_struct* tstr std::string field_name = (*f_iter)->get_name(); std::string cap_field_name = upcase_string(field_name); - out.indent() << cap_field_name << " = " << (*f_iter)->get_key() << endl; + out.indent() << cap_field_name << " = " << (*f_iter)->get_key() << '\n'; } - out << endl; + out << '\n'; } void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out.indent() << "FIELDS = {" << endl; + out.indent() << "FIELDS = {" << '\n'; out.indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (f_iter != fields.begin()) { - out << "," << endl; + out << "," << '\n'; } // generate the field docstrings within the FIELDS constant. no real better place... @@ -705,10 +703,10 @@ void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) (*f_iter)->get_req() == t_field::T_OPTIONAL); } out.indent_down(); - out << endl; - out.indent() << "}" << endl << endl; + out << '\n'; + out.indent() << "}" << '\n' << '\n'; - out.indent() << "def struct_fields; FIELDS; end" << endl << endl; + out.indent() << "def struct_fields; FIELDS; end" << '\n' << '\n'; } void t_rb_generator::generate_field_data(t_rb_ofstream& out, @@ -765,7 +763,7 @@ void t_rb_generator::generate_field_data(t_rb_ofstream& out, void t_rb_generator::begin_namespace(t_rb_ofstream& out, vector modules) { for (auto & module : modules) { - out.indent() << "module " << module << endl; + out.indent() << "module " << module << '\n'; out.indent_up(); } } @@ -774,7 +772,7 @@ void t_rb_generator::end_namespace(t_rb_ofstream& out, vector modul for (vector::reverse_iterator m_iter = modules.rbegin(); m_iter != modules.rend(); ++m_iter) { out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; } } @@ -787,25 +785,25 @@ void t_rb_generator::generate_service(t_service* tservice) { string f_service_name = namespace_dir_ + underscore(service_name_) + ".rb"; f_service_.open(f_service_name.c_str()); - f_service_ << rb_autogen_comment() << endl << render_require_thrift(); + f_service_ << rb_autogen_comment() << '\n' << render_require_thrift(); if (tservice->get_extends() != nullptr) { if (namespaced_) { f_service_ << "require '" << rb_namespace_to_path_prefix( tservice->get_extends()->get_program()->get_namespace("rb")) - << underscore(tservice->get_extends()->get_name()) << "'" << endl; + << underscore(tservice->get_extends()->get_name()) << "'" << '\n'; } else { f_service_ << "require '" << require_prefix_ - << underscore(tservice->get_extends()->get_name()) << "'" << endl; + << underscore(tservice->get_extends()->get_name()) << "'" << '\n'; } } - f_service_ << "require '" << require_prefix_ << underscore(program_name_) << "_types'" << endl - << endl; + f_service_ << "require '" << require_prefix_ << underscore(program_name_) << "_types'" << '\n' + << '\n'; begin_namespace(f_service_, ruby_modules(tservice->get_program())); - f_service_.indent() << "module " << capitalize(tservice->get_name()) << endl; + f_service_.indent() << "module " << capitalize(tservice->get_name()) << '\n'; f_service_.indent_up(); // Generate the three main parts of the service (well, two for now in PHP) @@ -814,7 +812,7 @@ void t_rb_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; end_namespace(f_service_, ruby_modules(tservice->get_program())); @@ -831,7 +829,7 @@ void t_rb_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_.indent() << "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_.indent() << "# HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -874,10 +872,10 @@ void t_rb_generator::generate_service_client(t_service* tservice) { extends_client = " < " + extends + "::Client "; } - f_service_.indent() << "class Client" << extends_client << endl; + f_service_.indent() << "class Client" << extends_client << '\n'; f_service_.indent_up(); - f_service_.indent() << "include ::Thrift::Client" << endl << endl; + f_service_.indent() << "include ::Thrift::Client" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -889,7 +887,7 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - f_service_.indent() << "def " << function_signature(*f_iter) << endl; + f_service_.indent() << "def " << function_signature(*f_iter) << '\n'; f_service_.indent_up(); f_service_.indent() << "send_" << funname << "("; @@ -902,20 +900,20 @@ void t_rb_generator::generate_service_client(t_service* tservice) { } f_service_ << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_.indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv_" << funname << "()" << endl; + f_service_ << "recv_" << funname << "()" << '\n'; } f_service_.indent_down(); - f_service_.indent() << "end" << endl; - f_service_ << endl; + f_service_.indent() << "end" << '\n'; + f_service_ << '\n'; - f_service_.indent() << "def send_" << function_signature(*f_iter) << endl; + f_service_.indent() << "def send_" << function_signature(*f_iter) << '\n'; f_service_.indent_up(); std::string argsname = capitalize((*f_iter)->get_name() + "_args"); @@ -927,10 +925,10 @@ void t_rb_generator::generate_service_client(t_service* tservice) { f_service_ << ", :" << (*fld_iter)->get_name() << " => " << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; f_service_.indent_down(); - f_service_.indent() << "end" << endl; + f_service_.indent() << "end" << '\n'; if (!(*f_iter)->is_oneway()) { std::string resultname = capitalize((*f_iter)->get_name() + "_result"); @@ -940,22 +938,22 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_ << endl; - f_service_.indent() << "def " << function_signature(&recv_function) << endl; + f_service_ << '\n'; + f_service_.indent() << "def " << function_signature(&recv_function) << '\n'; f_service_.indent_up(); - f_service_.indent() << "fname, mtype, rseqid = receive_message_begin()" << endl; - f_service_.indent() << "handle_exception(mtype)" << endl; + f_service_.indent() << "fname, mtype, rseqid = receive_message_begin()" << '\n'; + f_service_.indent() << "handle_exception(mtype)" << '\n'; - f_service_.indent() << "if reply_seqid(rseqid)==false" << endl; - f_service_.indent() << " raise \"seqid reply faild\"" << endl; - f_service_.indent() << "end" << endl; + f_service_.indent() << "if reply_seqid(rseqid)==false" << '\n'; + f_service_.indent() << " raise \"seqid reply faild\"" << '\n'; + f_service_.indent() << "end" << '\n'; - f_service_.indent() << "result = receive_message(" << resultname << ")" << endl; + f_service_.indent() << "result = receive_message(" << resultname << ")" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_.indent() << "return result.success unless result.success.nil?" << endl; + f_service_.indent() << "return result.success unless result.success.nil?" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); @@ -963,27 +961,27 @@ void t_rb_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_.indent() << "raise result." << (*x_iter)->get_name() << " unless result." - << (*x_iter)->get_name() << ".nil?" << endl; + << (*x_iter)->get_name() << ".nil?" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - f_service_.indent() << "return" << endl; + f_service_.indent() << "return" << '\n'; } else { f_service_.indent() << "raise " "::Thrift::ApplicationException.new(::Thrift::ApplicationException::" "MISSING_RESULT, '" << (*f_iter)->get_name() - << " failed: unknown result')" << endl; + << " failed: unknown result')" << '\n'; } // Close function f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } } f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1004,10 +1002,10 @@ void t_rb_generator::generate_service_server(t_service* tservice) { } // Generate the header portion - f_service_.indent() << "class Processor" << extends_processor << endl; + f_service_.indent() << "class Processor" << extends_processor << '\n'; f_service_.indent_up(); - f_service_.indent() << "include ::Thrift::Processor" << endl << endl; + f_service_.indent() << "include ::Thrift::Processor" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1015,7 +1013,7 @@ void t_rb_generator::generate_service_server(t_service* tservice) { } f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1026,13 +1024,13 @@ void t_rb_generator::generate_service_server(t_service* tservice) { void t_rb_generator::generate_process_function(t_service* tservice, t_function* tfunction) { (void)tservice; // Open function - f_service_.indent() << "def process_" << tfunction->get_name() << "(seqid, iprot, oprot)" << endl; + f_service_.indent() << "def process_" << tfunction->get_name() << "(seqid, iprot, oprot)" << '\n'; f_service_.indent_up(); string argsname = capitalize(tfunction->get_name()) + "_args"; string resultname = capitalize(tfunction->get_name()) + "_result"; - f_service_.indent() << "args = read_args(iprot, " << argsname << ")" << endl; + f_service_.indent() << "args = read_args(iprot, " << argsname << ")" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1040,12 +1038,12 @@ void t_rb_generator::generate_process_function(t_service* tservice, t_function* // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_.indent() << "result = " << resultname << ".new()" << endl; + f_service_.indent() << "result = " << resultname << ".new()" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_.indent() << "begin" << endl; + f_service_.indent() << "begin" << '\n'; f_service_.indent_up(); } @@ -1068,37 +1066,37 @@ void t_rb_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { f_service_.indent_down(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_.indent() << "rescue " << full_type_name((*x_iter)->get_type()) << " => " - << (*x_iter)->get_name() << endl; + << (*x_iter)->get_name() << '\n'; if (!tfunction->is_oneway()) { f_service_.indent_up(); f_service_.indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() - << endl; + << '\n'; f_service_.indent_down(); } } - f_service_.indent() << "end" << endl; + f_service_.indent() << "end" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_.indent() << "return" << endl; + f_service_.indent() << "return" << '\n'; f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; return; } f_service_.indent() << "write_result(result, oprot, '" << tfunction->get_name() << "', seqid)" - << endl; + << '\n'; // Close function f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1219,7 +1217,7 @@ void t_rb_generator::generate_rdoc(t_rb_ofstream& out, t_doc* tdoc) { } void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "def validate" << endl; + out.indent() << "def validate" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -1235,7 +1233,7 @@ void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t } else { out << " unless @" << field->get_name(); } - out << endl; + out << '\n'; } } @@ -1246,21 +1244,21 @@ void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t if (field->get_type()->is_enum()) { out.indent() << "unless @" << field->get_name() << ".nil? || " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(@" - << field->get_name() << ")" << endl; + << field->get_name() << ")" << '\n'; out.indent_up(); out.indent() << "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, " - "'Invalid value of field " << field->get_name() << "!')" << endl; + "'Invalid value of field " << field->get_name() << "!')" << '\n'; out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; } } out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "def validate" << endl; + out.indent() << "def validate" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -1268,25 +1266,25 @@ void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out, t_struct* t out.indent() << "raise(StandardError, 'Union fields are not set.') if get_set_field.nil? || get_value.nil?" - << endl; + << '\n'; // if field is an enum, check that its value is valid for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { const t_field* field = (*f_iter); if (field->get_type()->is_enum()) { - out.indent() << "if get_set_field == :" << field->get_name() << endl; + out.indent() << "if get_set_field == :" << field->get_name() << '\n'; out.indent() << " raise " "::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, " "'Invalid value of field " << field->get_name() << "!') unless " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(get_value)" - << endl; - out.indent() << "end" << endl; + << '\n'; + out.indent() << "end" << '\n'; } } out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } std::string t_rb_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc index 2742724a605..7bee974fc58 100644 --- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc @@ -31,7 +31,6 @@ using std::set; using std::string; using std::vector; -static const string endl("\n"); // avoid ostream << std::endl flushes static const string SERVICE_RESULT_VARIABLE("result_value"); static const string RESULT_STRUCT_SUFFIX("Result"); static const string RUST_RESERVED_WORDS[] @@ -521,9 +520,9 @@ void t_rs_generator::init_generator() { f_gen_.open(f_gen_name.c_str()); // header comment - f_gen_ << "// " << autogen_summary() << endl; - f_gen_ << "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" << endl; - f_gen_ << endl; + f_gen_ << "// " << autogen_summary() << '\n'; + f_gen_ << "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" << '\n'; + f_gen_ << '\n'; render_attributes_and_includes(); } @@ -532,11 +531,11 @@ void t_rs_generator::render_attributes_and_includes() { // turn off some compiler/clippy warnings // code may not be used - f_gen_ << "#![allow(dead_code)]" << endl; + f_gen_ << "#![allow(dead_code)]" << '\n'; // code always includes BTreeMap/BTreeSet/OrderedFloat - f_gen_ << "#![allow(unused_imports)]" << endl; + f_gen_ << "#![allow(unused_imports)]" << '\n'; // code might not include imports from crates - f_gen_ << "#![allow(unused_extern_crates)]" << endl; + f_gen_ << "#![allow(unused_extern_crates)]" << '\n'; // constructors take *all* struct parameters, which can trigger the "too many arguments" warning // some auto-gen'd types can be deeply nested. clippy recommends factoring them out which is hard // to autogen some methods may start with "is_" @@ -548,38 +547,38 @@ void t_rs_generator::render_attributes_and_includes() { // 2. When you define types out of order f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity, clippy::vec_box, " "clippy::wrong_self_convention)]" - << endl; + << '\n'; // prevent rustfmt from running against this file // lines are too long, code is (thankfully!) not visual-indented, etc. // can't use #[rustfmt::skip] see: https://github.com/rust-lang/rust/issues/54726 - f_gen_ << "#![cfg_attr(rustfmt, rustfmt_skip)]" << endl; - f_gen_ << endl; + f_gen_ << "#![cfg_attr(rustfmt, rustfmt_skip)]" << '\n'; + f_gen_ << '\n'; // add standard includes - f_gen_ << "use std::cell::RefCell;" << endl; - f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << endl; - f_gen_ << "use std::convert::{From, TryFrom};" << endl; - f_gen_ << "use std::default::Default;" << endl; - f_gen_ << "use std::error::Error;" << endl; - f_gen_ << "use std::fmt;" << endl; - f_gen_ << "use std::fmt::{Display, Formatter};" << endl; - f_gen_ << "use std::rc::Rc;" << endl; - f_gen_ << endl; - f_gen_ << "use thrift::OrderedFloat;" << endl; + f_gen_ << "use std::cell::RefCell;" << '\n'; + f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << '\n'; + f_gen_ << "use std::convert::{From, TryFrom};" << '\n'; + f_gen_ << "use std::default::Default;" << '\n'; + f_gen_ << "use std::error::Error;" << '\n'; + f_gen_ << "use std::fmt;" << '\n'; + f_gen_ << "use std::fmt::{Display, Formatter};" << '\n'; + f_gen_ << "use std::rc::Rc;" << '\n'; + f_gen_ << '\n'; + f_gen_ << "use thrift::OrderedFloat;" << '\n'; f_gen_ << "use thrift::{ApplicationError, ApplicationErrorKind, ProtocolError, " "ProtocolErrorKind, TThriftClient};" - << endl; + << '\n'; f_gen_ << "use thrift::protocol::{TFieldIdentifier, TListIdentifier, TMapIdentifier, " "TMessageIdentifier, TMessageType, TInputProtocol, TOutputProtocol, TSerializable, " "TSetIdentifier, TStructIdentifier, TType};" - << endl; - f_gen_ << "use thrift::protocol::field_id;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_message_type;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_sequence_number;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_service_call;" << endl; - f_gen_ << "use thrift::protocol::verify_required_field_exists;" << endl; - f_gen_ << "use thrift::server::TProcessor;" << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << "use thrift::protocol::field_id;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_message_type;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_sequence_number;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_service_call;" << '\n'; + f_gen_ << "use thrift::protocol::verify_required_field_exists;" << '\n'; + f_gen_ << "use thrift::server::TProcessor;" << '\n'; + f_gen_ << '\n'; // add all the program includes // NOTE: this is more involved than you would expect because of service extension @@ -615,13 +614,13 @@ void t_rs_generator::render_attributes_and_includes() { string_replace(module_namespace, ".", "::"); if (module_namespace.empty()) { - f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << endl; + f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << '\n'; } else { f_gen_ << "use crate::" << module_namespace << "::" << rust_snake_case(module_name) << ";" - << endl; + << '\n'; } } - f_gen_ << endl; + f_gen_ << '\n'; } } @@ -673,8 +672,8 @@ void t_rs_generator::render_const_value(const string& name, t_type* ttype, t_con f_gen_ << "pub const " << rust_upper_case(name) << ": " << to_rust_const_type(ttype) << " = "; render_const_value(ttype, tvalue, false); - f_gen_ << ";" << endl; - f_gen_ << endl; + f_gen_ << ";" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_const_value_holder(const string& name, @@ -686,19 +685,19 @@ void t_rs_generator::render_const_value_holder(const string& name, string holder_name("Const" + rust_camel_case(name)); - f_gen_ << indent() << "pub struct " << holder_name << ";" << endl; - f_gen_ << indent() << "impl " << holder_name << " {" << endl; + f_gen_ << indent() << "pub struct " << holder_name << ";" << '\n'; + f_gen_ << indent() << "impl " << holder_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << endl; + f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << '\n'; indent_up(); render_const_value(ttype, tvalue, true, false); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_const_value(t_type* ttype, @@ -748,10 +747,10 @@ void t_rs_generator::render_const_value(t_type* ttype, } else if (ttype->is_typedef()) { render_const_value(get_true_type(ttype), tvalue, is_owned, true); } else if (ttype->is_enum()) { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << to_rust_type(ttype) << "::try_from(" << tvalue->get_integer() - << ").expect(\"expecting valid const value\")" << endl; + f_gen_ << indent() << to_rust_type(ttype) << "::from(" << tvalue->get_integer() + << ")" << '\n'; indent_down(); f_gen_ << indent() << "}"; } else if (ttype->is_struct() || ttype->is_xception()) { @@ -772,21 +771,21 @@ void t_rs_generator::render_const_value(t_type* ttype, } if (!is_inline) { - f_gen_ << endl; + f_gen_ << '\n'; } } void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) { if (((t_struct*)ttype)->is_union()) { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << "unimplemented!()" << endl; + f_gen_ << indent() << "unimplemented!()" << '\n'; indent_down(); f_gen_ << indent() << "}"; } else { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << "unimplemented!()" << endl; + f_gen_ << indent() << "unimplemented!()" << '\n'; indent_down(); f_gen_ << indent() << "}"; } @@ -794,7 +793,7 @@ void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) { void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_list*)ttype)->get_elem_type(); - f_gen_ << "vec![" << endl; + f_gen_ << "vec![" << '\n'; indent_up(); const vector& elems = tvalue->get_list(); vector::const_iterator elem_iter; @@ -802,7 +801,7 @@ void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); render_const_value(elem_type, elem_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; } indent_down(); f_gen_ << indent() << "]"; @@ -810,7 +809,7 @@ void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_set*)ttype)->get_elem_type(); - f_gen_ << "BTreeSet::from([" << endl; + f_gen_ << "BTreeSet::from([" << '\n'; indent_up(); const vector& elems = tvalue->get_list(); vector::const_iterator elem_iter; @@ -818,7 +817,7 @@ void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); render_const_value(elem_type, elem_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; } indent_down(); f_gen_ << indent() << "])"; @@ -827,7 +826,7 @@ void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { t_type* key_type = ((t_map*)ttype)->get_key_type(); t_type* val_type = ((t_map*)ttype)->get_val_type(); - f_gen_ << "BTreeMap::from([" << endl; + f_gen_ << "BTreeMap::from([" << '\n'; indent_up(); const map& elems = tvalue->get_map(); @@ -836,16 +835,16 @@ void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { t_const_value* key_value = elem_iter->first; t_const_value* val_value = elem_iter->second; - f_gen_ << indent() << "(" << endl; + f_gen_ << indent() << "(" << '\n'; indent_up(); f_gen_ << indent(); render_const_value(key_type, key_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; f_gen_ << indent(); render_const_value(val_type, val_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; indent_down(); - f_gen_ << indent() << ")," << endl; + f_gen_ << indent() << ")," << '\n'; } indent_down(); f_gen_ << indent() << "])"; @@ -860,8 +859,8 @@ void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::generate_typedef(t_typedef* ttypedef) { std::string actual_type = to_rust_type(ttypedef->get_type()); f_gen_ << "pub type " << rust_safe_name(ttypedef->get_symbolic()) << " = " << actual_type << ";" - << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -879,13 +878,13 @@ void t_rs_generator::generate_enum(t_enum* tenum) { void t_rs_generator::render_enum_definition(t_enum* tenum, const string& enum_name) { render_rustdoc((t_doc*)tenum); - f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << "pub struct " << enum_name << "(pub i32);" << endl; - f_gen_ << endl; + f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << "pub struct " << enum_name << "(pub i32);" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_enum_impl(t_enum* tenum, const string& enum_name) { - f_gen_ << "impl " << enum_name << " {" << endl; + f_gen_ << "impl " << enum_name << " {" << '\n'; indent_up(); vector constants = tenum->get_constants(); @@ -898,114 +897,114 @@ void t_rs_generator::render_enum_impl(t_enum* tenum, const string& enum_name) { render_rustdoc((t_doc*)val); f_gen_ << indent() << "pub const " << rust_enum_variant_name(val->get_name()) << ": " << enum_name << " = " << enum_name << "(" << val->get_value() << ")" - << ";" << endl; + << ";" << '\n'; } } // array containing all IDL-defined enum variants { - f_gen_ << indent() << "pub const ENUM_VALUES: &'static [Self] = &[" << endl; + f_gen_ << indent() << "pub const ENUM_VALUES: &'static [Self] = &[" << '\n'; indent_up(); vector::iterator constants_iter; for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) { t_enum_value* val = (*constants_iter); - f_gen_ << indent() << "Self::" << rust_enum_variant_name(val->get_name()) << "," << endl; + f_gen_ << indent() << "Self::" << rust_enum_variant_name(val->get_name()) << "," << '\n'; } indent_down(); - f_gen_ << indent() << "];" << endl; + f_gen_ << indent() << "];" << '\n'; } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; - f_gen_ << "impl TSerializable for " << enum_name << " {" << endl; + f_gen_ << "impl TSerializable for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "#[allow(clippy::trivially_copy_pass_by_ref)]" << endl; + f_gen_ << indent() << "#[allow(clippy::trivially_copy_pass_by_ref)]" << '\n'; f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "o_prot.write_i32(self.0)" << endl; + f_gen_ << indent() << "o_prot.write_i32(self.0)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << enum_name << "> {" << endl; + << enum_name << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << endl; + f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << '\n'; f_gen_ << indent() << "Ok(" << enum_name << "::from(enum_value)" - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_enum_conversion(t_enum* tenum, const string& enum_name) { // From trait: i32 -> ENUM_TYPE - f_gen_ << "impl From for " << enum_name << " {" << endl; + f_gen_ << "impl From for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(i: i32) -> Self {" << endl; + f_gen_ << indent() << "fn from(i: i32) -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << "match i {" << endl; + f_gen_ << indent() << "match i {" << '\n'; indent_up(); vector constants = tenum->get_constants(); vector::iterator constants_iter; for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) { t_enum_value* val = (*constants_iter); f_gen_ << indent() << val->get_value() << " => " << enum_name - << "::" << rust_enum_variant_name(val->get_name()) << "," << endl; + << "::" << rust_enum_variant_name(val->get_name()) << "," << '\n'; } - f_gen_ << indent() << "_ => " << enum_name << "(i)" << endl; + f_gen_ << indent() << "_ => " << enum_name << "(i)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: &i32 -> ENUM_TYPE - f_gen_ << "impl From<&i32> for " << enum_name << " {" << endl; + f_gen_ << "impl From<&i32> for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(i: &i32) -> Self {" << endl; + f_gen_ << indent() << "fn from(i: &i32) -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << enum_name << "::from(*i)" << endl; + f_gen_ << indent() << enum_name << "::from(*i)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: ENUM_TYPE -> int - f_gen_ << "impl From<" << enum_name << "> for i32 {" << endl; + f_gen_ << "impl From<" << enum_name << "> for i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: " << enum_name << ") -> i32 {" << endl; + f_gen_ << indent() << "fn from(e: " << enum_name << ") -> i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "e.0" << endl; + f_gen_ << indent() << "e.0" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: &ENUM_TYPE -> int - f_gen_ << "impl From<&" << enum_name << "> for i32 {" << endl; + f_gen_ << "impl From<&" << enum_name << "> for i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: &" << enum_name << ") -> i32 {" << endl; + f_gen_ << indent() << "fn from(e: &" << enum_name << ") -> i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "e.0" << endl; + f_gen_ << indent() << "e.0" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -1056,8 +1055,8 @@ void t_rs_generator::render_struct_definition(const string& struct_name, } } f_gen_ << "#[derive(Clone, Debug" << (need_default ? ", Default" : "") - << ", Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << endl; + << ", Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << '\n'; // render the members if (!members.empty()) { @@ -1072,53 +1071,53 @@ void t_rs_generator::render_struct_definition(const string& struct_name, render_rustdoc((t_doc*)member); f_gen_ << indent() << visibility_qualifier(struct_type) << rust_field_name(member) << ": " - << rust_type << "," << endl; + << rust_type << "," << '\n'; } indent_down(); } - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct) { // error::Error trait - f_gen_ << "impl Error for " << struct_name << " {}" << endl; - f_gen_ << endl; + f_gen_ << "impl Error for " << struct_name << " {}" << '\n'; + f_gen_ << '\n'; // convert::From trait - f_gen_ << "impl From<" << struct_name << "> for thrift::Error {" << endl; + f_gen_ << "impl From<" << struct_name << "> for thrift::Error {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: " << struct_name << ") -> Self {" << endl; + f_gen_ << indent() << "fn from(e: " << struct_name << ") -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << "thrift::Error::User(Box::new(e))" << endl; + f_gen_ << indent() << "thrift::Error::User(Box::new(e))" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // fmt::Display trait - f_gen_ << "impl Display for " << struct_name << " {" << endl; + f_gen_ << "impl Display for " << struct_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << endl; + f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << '\n'; indent_up(); f_gen_ << indent() << "write!(f, " << "\"remote service threw " << tstruct->get_name() << "\"" // use *original* name - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_struct_impl(const string& struct_name, t_struct* tstruct, t_rs_generator::e_struct_type struct_type) { - f_gen_ << "impl " << struct_name << " {" << endl; + f_gen_ << "impl " << struct_name << " {" << '\n'; indent_up(); if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) { @@ -1131,10 +1130,10 @@ void t_rs_generator::render_struct_impl(const string& struct_name, if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) { indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; - f_gen_ << "impl TSerializable for " << struct_name << " {" << endl; + f_gen_ << "impl TSerializable for " << struct_name << " {" << '\n'; indent_up(); } @@ -1142,8 +1141,8 @@ void t_rs_generator::render_struct_impl(const string& struct_name, render_struct_sync_write(tstruct, struct_type); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_struct_constructor(const string& struct_name, @@ -1213,13 +1212,13 @@ void t_rs_generator::render_struct_constructor(const string& struct_name, string visibility(visibility_qualifier(struct_type)); f_gen_ << indent() << visibility << "fn new" << type_parameter_string << "(" << arg_string - << ") -> " << struct_name << " " << type_qualifier_string << "{" << endl; + << ") -> " << struct_name << " " << type_qualifier_string << "{" << '\n'; indent_up(); if (members.empty()) { - f_gen_ << indent() << struct_name << " {}" << endl; + f_gen_ << indent() << struct_name << " {}" << '\n'; } else { - f_gen_ << indent() << struct_name << " {" << endl; + f_gen_ << indent() << struct_name << " {" << '\n'; indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1228,18 +1227,18 @@ void t_rs_generator::render_struct_constructor(const string& struct_name, string member_name(rust_field_name(member)); if (is_optional(member_req)) { - f_gen_ << indent() << member_name << ": " << member_name << ".into()," << endl; + f_gen_ << indent() << member_name << ": " << member_name << ".into()," << '\n'; } else { - f_gen_ << indent() << member_name << "," << endl; + f_gen_ << indent() << member_name << "," << '\n'; } } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { @@ -1272,7 +1271,7 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { // maintaining a rendered branch count (while a little ugly) got me the // rendering I wanted with code that was reasonably understandable - f_gen_ << indent() << "fn ok_or(self) -> thrift::Result<" << rust_return_type << "> {" << endl; + f_gen_ << indent() << "fn ok_or(self) -> thrift::Result<" << rust_return_type << "> {" << '\n'; indent_up(); int rendered_branch_count = 0; @@ -1284,10 +1283,10 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { string field_name("self." + rust_field_name(tfield)); string branch_statement = rendered_branch_count == 0 ? "if" : "} else if"; - f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << endl; + f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << '\n'; indent_up(); f_gen_ << indent() << "Err(thrift::Error::User(Box::new(" << field_name << ".unwrap())))" - << endl; + << '\n'; indent_down(); rendered_branch_count++; @@ -1299,35 +1298,35 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { if (rendered_branch_count == 0) { // we have the unit return and this service call has no user-defined // exceptions. this means that we've a trivial return (happens with oneways) - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { // we have the unit return, but there are user-defined exceptions // if we've gotten this far then we have the default return (i.e. call successful) - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } } else { string branch_statement = rendered_branch_count == 0 ? "if" : "} else if"; f_gen_ << indent() << branch_statement << " self." << SERVICE_RESULT_VARIABLE << ".is_some() {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << endl; + f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << '\n'; indent_down(); - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); // if we haven't found a valid return value *or* a user exception // then we're in trouble; return a default error render_thrift_error("Application", "ApplicationError", "ApplicationErrorKind::MissingResult", "\"no result received for " + service_call_name + "\""); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union(t_struct* tstruct) { @@ -1343,32 +1342,32 @@ void t_rs_generator::render_union_definition(const string& union_name, t_struct* throw "cannot generate rust enum with 0 members"; // may be valid thrift, but it's invalid rust } - f_gen_ << "#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << "pub enum " << union_name << " {" << endl; + f_gen_ << "#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << "pub enum " << union_name << " {" << '\n'; indent_up(); vector::const_iterator member_iter; for (member_iter = members.begin(); member_iter != members.end(); ++member_iter) { t_field* tfield = (*member_iter); f_gen_ << indent() << rust_union_field_name(tfield) << "(" << to_rust_type(tfield->get_type()) - << ")," << endl; + << ")," << '\n'; } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_union_impl(const string& union_name, t_struct* tstruct) { - f_gen_ << "impl TSerializable for " << union_name << " {" << endl; + f_gen_ << "impl TSerializable for " << union_name << " {" << '\n'; indent_up(); render_union_sync_read(union_name, tstruct); render_union_sync_write(union_name, tstruct); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -1382,14 +1381,14 @@ void t_rs_generator::render_struct_sync_write(t_struct* tstruct, f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); // write struct header to output protocol // note: use the *original* struct name here f_gen_ << indent() - << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl; - f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl; + << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << '\n'; // write struct members to output protocol vector members = tstruct->get_sorted_members(); @@ -1404,30 +1403,30 @@ void t_rs_generator::render_struct_sync_write(t_struct* tstruct, } // write struct footer to output protocol - f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl; - f_gen_ << indent() << "o_prot.write_struct_end()" << endl; + f_gen_ << indent() << "o_prot.write_field_stop()?;" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_end()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union_sync_write(const string& union_name, t_struct* tstruct) { f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); // write struct header to output protocol // note: use the *original* struct name here f_gen_ << indent() - << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl; - f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl; + << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << '\n'; // write the enum field to the output protocol vector members = tstruct->get_sorted_members(); if (!members.empty()) { - f_gen_ << indent() << "match *self {" << endl; + f_gen_ << indent() << "match *self {" << '\n'; indent_up(); vector::iterator members_iter; for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1440,22 +1439,22 @@ void t_rs_generator::render_union_sync_write(const string& union_name, t_struct* } string match_var((ttype->is_base_type() && !ttype->is_string()) ? "f" : "ref f"); f_gen_ << indent() << union_name << "::" << rust_union_field_name(member) << "(" << match_var - << ") => {" << endl; + << ") => {" << '\n'; indent_up(); render_struct_field_sync_write("f", true, member, member_req); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } // write struct footer to output protocol - f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl; - f_gen_ << indent() << "o_prot.write_struct_end()" << endl; + f_gen_ << indent() << "o_prot.write_field_stop()?;" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_end()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_struct_field_sync_write(const string& field_var, @@ -1475,23 +1474,23 @@ void t_rs_generator::render_struct_field_sync_write(const string& field_var, if (is_optional(req)) { string let_var((actual_type->is_base_type() && !actual_type->is_string()) ? "fld_var" : "ref fld_var"); - f_gen_ << indent() << "if let Some(" << let_var << ") = " << field_var << " {" << endl; + f_gen_ << indent() << "if let Some(" << let_var << ") = " << field_var << " {" << '\n'; indent_up(); - f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl; + f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << '\n'; render_type_sync_write("fld_var", true, field_type); - f_gen_ << indent() << "o_prot.write_field_end()?" << endl; + f_gen_ << indent() << "o_prot.write_field_end()?" << '\n'; indent_down(); /* FIXME: rethink how I deal with OPT_IN_REQ_OUT if (req == t_field::T_OPT_IN_REQ_OUT) { - f_gen_ << indent() << "let field_ident = " << field_ident_string << ";" << endl; - f_gen_ << indent() << "o_prot.write_field_begin(&field_ident)?;" << endl; - f_gen_ << indent() << "o_prot.write_field_end()?;" << endl; + f_gen_ << indent() << "let field_ident = " << field_ident_string << ";" << '\n'; + f_gen_ << indent() << "o_prot.write_field_begin(&field_ident)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_field_end()?;" << '\n'; }*/ - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } else { - f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl; + f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << '\n'; render_type_sync_write(field_var, field_var_is_ref, tfield->get_type()); - f_gen_ << indent() << "o_prot.write_field_end()?;" << endl; + f_gen_ << indent() << "o_prot.write_field_end()?;" << '\n'; } } @@ -1506,32 +1505,32 @@ void t_rs_generator::render_type_sync_write(const string& type_var, case t_base_type::TYPE_STRING: { string ref(type_var_is_ref ? "" : "&"); if (tbase_type->is_binary()) { - f_gen_ << indent() << "o_prot.write_bytes(" + ref + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_bytes(" + ref + type_var + ")?;" << '\n'; } else { - f_gen_ << indent() << "o_prot.write_string(" + ref + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_string(" + ref + type_var + ")?;" << '\n'; } return; } case t_base_type::TYPE_UUID: - f_gen_ << indent() << "o_prot.write_uuid(&" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_uuid(&" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_BOOL: - f_gen_ << indent() << "o_prot.write_bool(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_bool(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I8: - f_gen_ << indent() << "o_prot.write_i8(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i8(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I16: - f_gen_ << indent() << "o_prot.write_i16(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i16(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I32: - f_gen_ << indent() << "o_prot.write_i32(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i32(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I64: - f_gen_ << indent() << "o_prot.write_i64(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i64(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_DOUBLE: - f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << endl; + f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << '\n'; return; default: throw "compiler error: unhandled type"; @@ -1541,7 +1540,7 @@ void t_rs_generator::render_type_sync_write(const string& type_var, render_type_sync_write(type_var, type_var_is_ref, ttypedef->get_type()); return; } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) { - f_gen_ << indent() << type_var + ".write_to_out_protocol(o_prot)?;" << endl; + f_gen_ << indent() << type_var + ".write_to_out_protocol(o_prot)?;" << '\n'; return; } else if (ttype->is_map()) { render_map_sync_write(type_var, type_var_is_ref, (t_map*)ttype); @@ -1566,15 +1565,15 @@ void t_rs_generator::render_list_sync_write(const string& list_var, << "&TListIdentifier::new(" << to_rust_field_type_enum(elem_type) << ", " << list_var << ".len() as i32" << ")" - << ")?;" << endl; + << ")?;" << '\n'; string ref(list_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for e in " << ref << list_var << " {" << endl; + f_gen_ << indent() << "for e in " << ref << list_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(elem_type, "e"), true, elem_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_list_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_list_end()?;" << '\n'; } void t_rs_generator::render_set_sync_write(const string& set_var, @@ -1586,15 +1585,15 @@ void t_rs_generator::render_set_sync_write(const string& set_var, << "&TSetIdentifier::new(" << to_rust_field_type_enum(elem_type) << ", " << set_var << ".len() as i32" << ")" - << ")?;" << endl; + << ")?;" << '\n'; string ref(set_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for e in " << ref << set_var << " {" << endl; + f_gen_ << indent() << "for e in " << ref << set_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(elem_type, "e"), true, elem_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_set_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_set_end()?;" << '\n'; } void t_rs_generator::render_map_sync_write(const string& map_var, @@ -1606,16 +1605,16 @@ void t_rs_generator::render_map_sync_write(const string& map_var, f_gen_ << indent() << "o_prot.write_map_begin(" << "&TMapIdentifier::new(" << to_rust_field_type_enum(key_type) << ", " << to_rust_field_type_enum(val_type) << ", " << map_var << ".len() as i32)" - << ")?;" << endl; + << ")?;" << '\n'; string ref(map_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for (k, v) in " << ref << map_var << " {" << endl; + f_gen_ << indent() << "for (k, v) in " << ref << map_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(key_type, "k"), true, key_type); render_type_sync_write(string_container_write_variable(val_type, "v"), true, val_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_map_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_map_end()?;" << '\n'; } string t_rs_generator::string_container_write_variable(t_type* ttype, const string& base_var) { @@ -1651,11 +1650,11 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, t_rs_generator::e_struct_type struct_type) { f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << struct_name << "> {" << endl; + << struct_name << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl; + f_gen_ << indent() << "i_prot.read_struct_begin()?;" << '\n'; // create temporary variables: one for each field in the struct const vector members = tstruct->get_sorted_members(); @@ -1671,55 +1670,55 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, } else { f_gen_ << "None;"; } - f_gen_ << endl; + f_gen_ << '\n'; } // now loop through the fields we've received - f_gen_ << indent() << "loop {" << endl; // start loop + f_gen_ << indent() << "loop {" << '\n'; // start loop indent_up(); // break out if you've found the Stop field - f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl; - f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl; + f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << '\n'; + f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << '\n'; indent_up(); - f_gen_ << indent() << "break;" << endl; + f_gen_ << indent() << "break;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; // now read all the fields found // avoid clippy::match_single_binding if (members.empty()) { - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; } else { - f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; - f_gen_ << indent() << "match field_id {" << endl; // start match + f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << '\n'; + f_gen_ << indent() << "match field_id {" << '\n'; // start match indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { t_field* tfield = (*members_iter); - f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << endl; + f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << '\n'; indent_up(); render_type_sync_read("val", tfield->get_type()); - f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << endl; + f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // default case (skip fields) - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; // finish match + f_gen_ << indent() << "};" << '\n'; // finish match } - f_gen_ << indent() << "i_prot.read_field_end()?;" << endl; + f_gen_ << indent() << "i_prot.read_field_end()?;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // finish loop - f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // read message footer from the wire + f_gen_ << indent() << "}" << '\n'; // finish loop + f_gen_ << indent() << "i_prot.read_struct_end()?;" << '\n'; // read message footer from the wire // verify that all required fields exist for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1729,15 +1728,15 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, f_gen_ << indent() << "verify_required_field_exists(" << "\"" << struct_name << "." << rust_field_name(tfield) << "\"" << ", " - << "&" << struct_field_read_temp_variable(tfield) << ")?;" << endl; + << "&" << struct_field_read_temp_variable(tfield) << ")?;" << '\n'; } } // construct the struct if (members.size() == 0) { - f_gen_ << indent() << "let ret = " << struct_name << " {};" << endl; + f_gen_ << indent() << "let ret = " << struct_name << " {};" << '\n'; } else { - f_gen_ << indent() << "let ret = " << struct_name << " {" << endl; + f_gen_ << indent() << "let ret = " << struct_name << " {" << '\n'; indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1746,109 +1745,119 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, string field_name(rust_field_name(tfield)); string field_key = struct_field_read_temp_variable(tfield); if (is_optional(req)) { - f_gen_ << indent() << field_name << ": " << field_key << "," << endl; + f_gen_ << indent() << field_name << ": " << field_key << "," << '\n'; } else { f_gen_ << indent() << field_name << ": " << field_key << ".expect(\"auto-generated code should have checked for presence of required " "fields\")" - << "," << endl; + << "," << '\n'; } } indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; } // return the constructed value - f_gen_ << indent() << "Ok(ret)" << endl; + f_gen_ << indent() << "Ok(ret)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union_sync_read(const string& union_name, t_struct* tstruct) { f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << union_name << "> {" << endl; + << union_name << "> {" << '\n'; indent_up(); // create temporary variables to hold the // completed union as well as a count of fields read - f_gen_ << indent() << "let mut ret: Option<" << union_name << "> = None;" << endl; - f_gen_ << indent() << "let mut received_field_count = 0;" << endl; + f_gen_ << indent() << "let mut ret: Option<" << union_name << "> = None;" << '\n'; + f_gen_ << indent() << "let mut received_field_count = 0;" << '\n'; // read the struct preamble - f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl; + f_gen_ << indent() << "i_prot.read_struct_begin()?;" << '\n'; // now loop through the fields we've received - f_gen_ << indent() << "loop {" << endl; // start loop + f_gen_ << indent() << "loop {" << '\n'; // start loop indent_up(); // break out if you've found the Stop field - f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl; - f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl; + f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << '\n'; + f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << '\n'; indent_up(); - f_gen_ << indent() << "break;" << endl; + f_gen_ << indent() << "break;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; // now read all the fields found - f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; - f_gen_ << indent() << "match field_id {" << endl; // start match + f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << '\n'; + f_gen_ << indent() << "match field_id {" << '\n'; // start match indent_up(); const vector members = tstruct->get_sorted_members(); vector::const_iterator members_iter; for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { t_field* member = (*members_iter); - f_gen_ << indent() << rust_safe_field_id(member->get_key()) << " => {" << endl; + f_gen_ << indent() << rust_safe_field_id(member->get_key()) << " => {" << '\n'; indent_up(); render_type_sync_read("val", member->get_type()); - f_gen_ << indent() << "if ret.is_none() {" << endl; + f_gen_ << indent() << "if ret.is_none() {" << '\n'; indent_up(); f_gen_ << indent() << "ret = Some(" << union_name << "::" << rust_union_field_name(member) - << "(val));" << endl; + << "(val));" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "received_field_count += 1;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "received_field_count += 1;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // default case (skip fields) - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; - f_gen_ << indent() << "received_field_count += 1;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; + f_gen_ << indent() << "received_field_count += 1;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; // finish match - f_gen_ << indent() << "i_prot.read_field_end()?;" << endl; + f_gen_ << indent() << "};" << '\n'; // finish match + f_gen_ << indent() << "i_prot.read_field_end()?;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // finish loop - f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // finish reading message from wire + f_gen_ << indent() << "}" << '\n'; // finish loop + f_gen_ << indent() << "i_prot.read_struct_end()?;" << '\n'; // finish reading message from wire // return the value or an error - f_gen_ << indent() << "if received_field_count == 0 {" << endl; + f_gen_ << indent() << "if received_field_count == 0 {" << '\n'; indent_up(); render_thrift_error("Protocol", "ProtocolError", "ProtocolErrorKind::InvalidData", "\"received empty union from remote " + union_name + "\""); indent_down(); - f_gen_ << indent() << "} else if received_field_count > 1 {" << endl; + f_gen_ << indent() << "} else if received_field_count > 1 {" << '\n'; indent_up(); render_thrift_error("Protocol", "ProtocolError", "ProtocolErrorKind::InvalidData", "\"received multiple fields for union from remote " + union_name + "\""); indent_down(); - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else if let Some(ret) = ret {" << '\n'; indent_up(); - f_gen_ << indent() << "Ok(ret.expect(\"return value should have been constructed\"))" << endl; + f_gen_ << indent() << "Ok(ret)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "} else {" << '\n'; + indent_up(); + f_gen_ << indent() << "Err(" << '\n'; + indent_up(); + f_gen_ << indent() << "thrift::Error::Protocol(" << '\n'; + f_gen_ << indent() << " ProtocolError::new(ProtocolErrorKind::InvalidData, \"return value should have been constructed\")" << '\n'; + f_gen_ << indent() << ")" << '\n'; + indent_down(); + f_gen_ << indent() << ")" << '\n'; + indent_down(); + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } // Construct the rust representation of all supported types from the wire. @@ -1860,32 +1869,32 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype throw "cannot read field of type TYPE_VOID from input protocol"; case t_base_type::TYPE_STRING: if (tbase_type->is_binary()) { - f_gen_ << indent() << "let " << type_var << " = i_prot.read_bytes()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_bytes()?;" << '\n'; } else { - f_gen_ << indent() << "let " << type_var << " = i_prot.read_string()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_string()?;" << '\n'; } return; case t_base_type::TYPE_UUID: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_uuid()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_uuid()?;" << '\n'; return; case t_base_type::TYPE_BOOL: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_bool()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_bool()?;" << '\n'; return; case t_base_type::TYPE_I8: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i8()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i8()?;" << '\n'; return; case t_base_type::TYPE_I16: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i16()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i16()?;" << '\n'; return; case t_base_type::TYPE_I32: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i32()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i32()?;" << '\n'; return; case t_base_type::TYPE_I64: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i64()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i64()?;" << '\n'; return; case t_base_type::TYPE_DOUBLE: f_gen_ << indent() << "let " << type_var << " = OrderedFloat::from(i_prot.read_double()?);" - << endl; + << '\n'; return; default: throw "compiler error: unhandled type"; @@ -1905,7 +1914,7 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) { string read_call(to_rust_type(ttype) + "::read_from_in_protocol(i_prot)?"); read_call = is_boxed ? "Box::new(" + read_call + ")" : read_call; - f_gen_ << indent() << "let " << type_var << " = " << read_call << ";" << endl; + f_gen_ << indent() << "let " << type_var << " = " << read_call << ";" << '\n'; return; } else if (ttype->is_map()) { render_map_sync_read((t_map*)ttype, type_var); @@ -1925,42 +1934,42 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype void t_rs_generator::render_list_sync_read(t_list* tlist, const string& list_var) { t_type* elem_type = tlist->get_elem_type(); - f_gen_ << indent() << "let list_ident = i_prot.read_list_begin()?;" << endl; + f_gen_ << indent() << "let list_ident = i_prot.read_list_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << list_var << ": " << to_rust_type((t_type*)tlist) - << " = Vec::with_capacity(list_ident.size as usize);" << endl; - f_gen_ << indent() << "for _ in 0..list_ident.size {" << endl; + << " = Vec::with_capacity(list_ident.size as usize);" << '\n'; + f_gen_ << indent() << "for _ in 0..list_ident.size {" << '\n'; indent_up(); string list_elem_var = tmp("list_elem_"); render_type_sync_read(list_elem_var, elem_type); - f_gen_ << indent() << list_var << ".push(" << list_elem_var << ");" << endl; + f_gen_ << indent() << list_var << ".push(" << list_elem_var << ");" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_list_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_list_end()?;" << '\n'; } // Construct the rust representation of a set from the wire. void t_rs_generator::render_set_sync_read(t_set* tset, const string& set_var) { t_type* elem_type = tset->get_elem_type(); - f_gen_ << indent() << "let set_ident = i_prot.read_set_begin()?;" << endl; + f_gen_ << indent() << "let set_ident = i_prot.read_set_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << set_var << ": " << to_rust_type((t_type*)tset) - << " = BTreeSet::new();" << endl; - f_gen_ << indent() << "for _ in 0..set_ident.size {" << endl; + << " = BTreeSet::new();" << '\n'; + f_gen_ << indent() << "for _ in 0..set_ident.size {" << '\n'; indent_up(); string set_elem_var = tmp("set_elem_"); render_type_sync_read(set_elem_var, elem_type); - f_gen_ << indent() << set_var << ".insert(" << set_elem_var << ");" << endl; + f_gen_ << indent() << set_var << ".insert(" << set_elem_var << ");" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_set_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_set_end()?;" << '\n'; } // Construct the rust representation of a map from the wire. @@ -1968,10 +1977,10 @@ void t_rs_generator::render_map_sync_read(t_map* tmap, const string& map_var) { t_type* key_type = tmap->get_key_type(); t_type* val_type = tmap->get_val_type(); - f_gen_ << indent() << "let map_ident = i_prot.read_map_begin()?;" << endl; + f_gen_ << indent() << "let map_ident = i_prot.read_map_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << map_var << ": " << to_rust_type((t_type*)tmap) - << " = BTreeMap::new();" << endl; - f_gen_ << indent() << "for _ in 0..map_ident.size {" << endl; + << " = BTreeMap::new();" << '\n'; + f_gen_ << indent() << "for _ in 0..map_ident.size {" << '\n'; indent_up(); @@ -1980,12 +1989,12 @@ void t_rs_generator::render_map_sync_read(t_map* tmap, const string& map_var) { string val_elem_var = tmp("map_val_"); render_type_sync_read(val_elem_var, val_type); f_gen_ << indent() << map_var << ".insert(" << key_elem_var << ", " << val_elem_var << ");" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_map_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_map_end()?;" << '\n'; } string t_rs_generator::struct_field_read_temp_variable(t_field* tfield) { @@ -2036,7 +2045,7 @@ void t_rs_generator::render_sync_client(t_service* tservice) { render_sync_client_definition_and_impl(client_impl_name); render_sync_client_tthriftclient_impl(client_impl_name); render_sync_client_marker_trait_impls(tservice, client_impl_name); - f_gen_ << endl; + f_gen_ << '\n'; render_sync_client_process_impl(tservice); } @@ -2048,7 +2057,7 @@ void t_rs_generator::render_sync_client_trait(t_service* tservice) { } render_rustdoc((t_doc*)tservice); - f_gen_ << "pub trait " << rust_sync_client_trait_name(tservice) << extension << " {" << endl; + f_gen_ << "pub trait " << rust_sync_client_trait_name(tservice) << extension << " {" << '\n'; indent_up(); const std::vector functions = tservice->get_functions(); @@ -2060,25 +2069,25 @@ void t_rs_generator::render_sync_client_trait(t_service* tservice) { string func_return = to_rust_type(tfunc->get_returntype()); render_rustdoc((t_doc*)tfunc); f_gen_ << indent() << "fn " << func_name << func_args << " -> thrift::Result<" << func_return - << ">;" << endl; + << ">;" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_marker_trait(t_service* tservice) { f_gen_ << indent() << "pub trait " << rust_sync_client_marker_trait_name(tservice) << " {}" - << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_marker_trait_impls(t_service* tservice, const string& impl_struct_name) { f_gen_ << indent() << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << rust_namespace(tservice) << rust_sync_client_marker_trait_name(tservice) << " for " << impl_struct_name - << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {}" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {}" << '\n'; t_service* extends = tservice->get_extends(); if (extends) { @@ -2090,64 +2099,64 @@ void t_rs_generator::render_sync_client_definition_and_impl(const string& client // render the definition for the client struct f_gen_ << "pub struct " << client_impl_name << SYNC_CLIENT_GENERIC_BOUND_VARS << " " - << SYNC_CLIENT_GENERIC_BOUNDS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUNDS << " {" << '\n'; indent_up(); - f_gen_ << indent() << "_i_prot: IP," << endl; - f_gen_ << indent() << "_o_prot: OP," << endl; - f_gen_ << indent() << "_sequence_number: i32," << endl; + f_gen_ << indent() << "_i_prot: IP," << '\n'; + f_gen_ << indent() << "_o_prot: OP," << '\n'; + f_gen_ << indent() << "_sequence_number: i32," << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // render the struct implementation // this includes the new() function as well as the helper send/recv methods for each service call f_gen_ << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << client_impl_name - << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {" << '\n'; indent_up(); render_sync_client_lifecycle_functions(client_impl_name); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_lifecycle_functions(const string& client_struct) { f_gen_ << indent() << "pub fn new(input_protocol: IP, output_protocol: OP) -> " << client_struct - << SYNC_CLIENT_GENERIC_BOUND_VARS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " {" << '\n'; indent_up(); f_gen_ << indent() << client_struct - << " { _i_prot: input_protocol, _o_prot: output_protocol, _sequence_number: 0 }" << endl; + << " { _i_prot: input_protocol, _o_prot: output_protocol, _sequence_number: 0 }" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_client_tthriftclient_impl(const string& client_impl_name) { f_gen_ << indent() << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " TThriftClient for " << client_impl_name << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS - << " {" << endl; + << " {" << '\n'; indent_up(); f_gen_ << indent() << "fn i_prot_mut(&mut self) -> &mut dyn TInputProtocol { &mut self._i_prot }" - << endl; + << '\n'; f_gen_ << indent() << "fn o_prot_mut(&mut self) -> &mut dyn TOutputProtocol { &mut self._o_prot }" - << endl; - f_gen_ << indent() << "fn sequence_number(&self) -> i32 { self._sequence_number }" << endl; + << '\n'; + f_gen_ << indent() << "fn sequence_number(&self) -> i32 { self._sequence_number }" << '\n'; f_gen_ << indent() << "fn increment_sequence_number(&mut self) -> i32 { self._sequence_number += 1; " "self._sequence_number }" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_process_impl(t_service* tservice) { string marker_extension = "" + sync_client_marker_traits_for_extension(tservice); f_gen_ << "impl " << rust_sync_client_trait_name(tservice) << " for C {" << endl; + << marker_extension << "> " << rust_sync_client_trait_name(tservice) << " for C {" << '\n'; indent_up(); const std::vector functions = tservice->get_functions(); @@ -2158,8 +2167,8 @@ void t_rs_generator::render_sync_client_process_impl(t_service* tservice) { } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } string t_rs_generator::sync_client_marker_traits_for_extension(t_service* tservice) { @@ -2182,35 +2191,35 @@ void t_rs_generator::render_sync_send_recv_wrapper(t_function* tfunc) { string func_return = to_rust_type(tfunc->get_returntype()); f_gen_ << indent() << "fn " << func_name << func_decl_args << " -> thrift::Result<" << func_return - << "> {" << endl; + << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "(" << endl; + f_gen_ << indent() << "(" << '\n'; indent_up(); render_sync_send(tfunc); indent_down(); - f_gen_ << indent() << ")?;" << endl; + f_gen_ << indent() << ")?;" << '\n'; if (tfunc->is_oneway()) { - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { render_sync_recv(tfunc); } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_send(t_function* tfunc) { - f_gen_ << indent() << "{" << endl; + f_gen_ << indent() << "{" << '\n'; indent_up(); // increment the sequence number and generate the call header string message_type = tfunc->is_oneway() ? "TMessageType::OneWay" : "TMessageType::Call"; - f_gen_ << indent() << "self.increment_sequence_number();" << endl; + f_gen_ << indent() << "self.increment_sequence_number();" << '\n'; f_gen_ << indent() << "let message_ident = " << "TMessageIdentifier::new(\"" << tfunc->get_name() << "\", " // note: use *original* name << message_type << ", " - << "self.sequence_number());" << endl; + << "self.sequence_number());" << '\n'; // pack the arguments into the containing struct that we'll write out over the wire // note that this struct is generated even if we have 0 args ostringstream struct_definition; @@ -2226,50 +2235,50 @@ void t_rs_generator::render_sync_send(t_function* tfunc) { struct_fields = struct_fields.substr(0, struct_fields.size() - 2); // strip trailing comma } f_gen_ << indent() << "let call_args = " << service_call_args_struct_name(tfunc) << " { " - << struct_fields << " };" << endl; + << struct_fields << " };" << '\n'; // write everything over the wire - f_gen_ << indent() << "self.o_prot_mut().write_message_begin(&message_ident)?;" << endl; + f_gen_ << indent() << "self.o_prot_mut().write_message_begin(&message_ident)?;" << '\n'; f_gen_ << indent() << "call_args.write_to_out_protocol(self.o_prot_mut())?;" - << endl; // written even if we have 0 args - f_gen_ << indent() << "self.o_prot_mut().write_message_end()?;" << endl; - f_gen_ << indent() << "self.o_prot_mut().flush()" << endl; + << '\n'; // written even if we have 0 args + f_gen_ << indent() << "self.o_prot_mut().write_message_end()?;" << '\n'; + f_gen_ << indent() << "self.o_prot_mut().flush()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_recv(t_function* tfunc) { - f_gen_ << indent() << "{" << endl; + f_gen_ << indent() << "{" << '\n'; indent_up(); - f_gen_ << indent() << "let message_ident = self.i_prot_mut().read_message_begin()?;" << endl; + f_gen_ << indent() << "let message_ident = self.i_prot_mut().read_message_begin()?;" << '\n'; f_gen_ << indent() << "verify_expected_sequence_number(self.sequence_number(), message_ident.sequence_number)?;" - << endl; + << '\n'; f_gen_ << indent() << "verify_expected_service_call(\"" << tfunc->get_name() - << "\", &message_ident.name)?;" << endl; // note: use *original* name + << "\", &message_ident.name)?;" << '\n'; // note: use *original* name // FIXME: replace with a "try" block - f_gen_ << indent() << "if message_ident.message_type == TMessageType::Exception {" << endl; + f_gen_ << indent() << "if message_ident.message_type == TMessageType::Exception {" << '\n'; indent_up(); f_gen_ << indent() << "let remote_error = " "thrift::Error::read_application_error_from_in_protocol(self.i_prot_mut())?;" - << endl; - f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl; - f_gen_ << indent() << "return Err(thrift::Error::Application(remote_error))" << endl; + << '\n'; + f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << '\n'; + f_gen_ << indent() << "return Err(thrift::Error::Application(remote_error))" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; f_gen_ << indent() << "verify_expected_message_type(TMessageType::Reply, message_ident.message_type)?;" - << endl; + << '\n'; f_gen_ << indent() << "let result = " << service_call_result_struct_name(tfunc) - << "::read_from_in_protocol(self.i_prot_mut())?;" << endl; - f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl; - f_gen_ << indent() << "result.ok_or()" << endl; + << "::read_from_in_protocol(self.i_prot_mut())?;" << '\n'; + f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << '\n'; + f_gen_ << indent() << "result.ok_or()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } string t_rs_generator::rust_sync_service_call_declaration(t_function* tfunc, bool self_is_mutable) { @@ -2400,7 +2409,7 @@ void t_rs_generator::render_sync_handler_trait(t_service* tservice) { std::vector::const_iterator func_iter; render_rustdoc((t_doc*)tservice); - f_gen_ << "pub trait " << rust_sync_handler_trait_name(tservice) << extension << " {" << endl; + f_gen_ << "pub trait " << rust_sync_handler_trait_name(tservice) << extension << " {" << '\n'; indent_up(); for (func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) { t_function* tfunc = (*func_iter); @@ -2409,11 +2418,11 @@ void t_rs_generator::render_sync_handler_trait(t_service* tservice) { string func_return = to_rust_type(tfunc->get_returntype()); render_rustdoc((t_doc*)tfunc); f_gen_ << indent() << "fn " << func_name << func_args << " -> thrift::Result<" << func_return - << ">;" << endl; + << ">;" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservice) { @@ -2422,36 +2431,36 @@ void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservi // struct f_gen_ << indent() << "pub struct " << service_processor_name << " {" << endl; + << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "handler: H," << endl; + f_gen_ << indent() << "pub handler: H," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // delegating impl f_gen_ << indent() << "impl " << service_processor_name - << " {" << endl; + << " {" << '\n'; indent_up(); - f_gen_ << indent() << "pub fn new(handler: H) -> " << service_processor_name << " {" << endl; + f_gen_ << indent() << "pub fn new(handler: H) -> " << service_processor_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << service_processor_name << " {" << endl; + f_gen_ << indent() << service_processor_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "handler," << endl; + f_gen_ << indent() << "handler," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; render_sync_process_delegation_functions(tservice); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // actual impl string service_actual_processor_name = rust_sync_processor_impl_name(tservice); - f_gen_ << indent() << "pub struct " << service_actual_processor_name << ";" << endl; - f_gen_ << endl; - f_gen_ << indent() << "impl " << service_actual_processor_name << " {" << endl; + f_gen_ << indent() << "pub struct " << service_actual_processor_name << ";" << '\n'; + f_gen_ << '\n'; + f_gen_ << indent() << "impl " << service_actual_processor_name << " {" << '\n'; indent_up(); vector functions = tservice->get_functions(); @@ -2462,44 +2471,44 @@ void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservi } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // processor impl f_gen_ << indent() << "impl TProcessor for " - << service_processor_name << " {" << endl; + << service_processor_name << " {" << '\n'; indent_up(); f_gen_ << indent() << "fn process(&self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) " "-> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "let message_ident = i_prot.read_message_begin()?;" << endl; + f_gen_ << indent() << "let message_ident = i_prot.read_message_begin()?;" << '\n'; f_gen_ << indent() << "let res = match &*message_ident.name {" - << endl; // [sigh] explicit deref coercion + << '\n'; // [sigh] explicit deref coercion indent_up(); render_process_match_statements(tservice); - f_gen_ << indent() << "method => {" << endl; + f_gen_ << indent() << "method => {" << '\n'; indent_up(); render_thrift_error("Application", "ApplicationError", "ApplicationErrorKind::UnknownMethod", "format!(\"unknown method {}\", method)"); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; f_gen_ << indent() << "thrift::server::handle_process_result(&message_ident, res, o_prot)" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_process_delegation_functions(t_service* tservice) { @@ -2514,7 +2523,7 @@ void t_rs_generator::render_sync_process_delegation_functions(t_service* tservic << "incoming_sequence_number: i32, " << "i_prot: &mut dyn TInputProtocol, " << "o_prot: &mut dyn TOutputProtocol) " - << "-> thrift::Result<()> {" << endl; + << "-> thrift::Result<()> {" << '\n'; indent_up(); f_gen_ << indent() << actual_processor << "::" << function_name << "(" @@ -2522,10 +2531,10 @@ void t_rs_generator::render_sync_process_delegation_functions(t_service* tservic << "incoming_sequence_number, " << "i_prot, " << "o_prot" - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } t_service* extends = tservice->get_extends(); @@ -2540,12 +2549,12 @@ void t_rs_generator::render_process_match_statements(t_service* tservice) { for (func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) { t_function* tfunc = (*func_iter); f_gen_ << indent() << "\"" << tfunc->get_name() << "\"" - << " => {" << endl; // note: use *original* name + << " => {" << '\n'; // note: use *original* name indent_up(); f_gen_ << indent() << "self.process_" << rust_snake_case(tfunc->get_name()) - << "(message_ident.sequence_number, i_prot, o_prot)" << endl; + << "(message_ident.sequence_number, i_prot, o_prot)" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } t_service* extends = tservice->get_extends(); @@ -2568,90 +2577,90 @@ void t_rs_generator::render_sync_process_function(t_function* tfunc, const strin << "(handler: &H, " << sequence_number_param << ": i32, " << "i_prot: &mut dyn TInputProtocol, " << output_protocol_param << ": &mut dyn TOutputProtocol) " - << "-> thrift::Result<()> {" << endl; + << "-> thrift::Result<()> {" << '\n'; indent_up(); // *always* read arguments from the input protocol f_gen_ << indent() << "let " << (has_non_void_args(tfunc) ? "args" : "_") << " = " - << service_call_args_struct_name(tfunc) << "::read_from_in_protocol(i_prot)?;" << endl; + << service_call_args_struct_name(tfunc) << "::read_from_in_protocol(i_prot)?;" << '\n'; f_gen_ << indent() << "match handler." << service_call_handler_function_name(tfunc) - << rust_sync_service_call_invocation(tfunc, "args.") << " {" << endl; // start match + << rust_sync_service_call_invocation(tfunc, "args.") << " {" << '\n'; // start match indent_up(); // handler succeeded string handler_return_variable = tfunc->is_oneway() || tfunc->get_returntype()->is_void() ? "_" : "handler_return"; - f_gen_ << indent() << "Ok(" << handler_return_variable << ") => {" << endl; + f_gen_ << indent() << "Ok(" << handler_return_variable << ") => {" << '\n'; indent_up(); render_sync_handler_succeeded(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; // handler failed - f_gen_ << indent() << "Err(e) => {" << endl; + f_gen_ << indent() << "Err(e) => {" << '\n'; indent_up(); render_sync_handler_failed(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // end match + f_gen_ << indent() << "}" << '\n'; // end match indent_down(); - f_gen_ << indent() << "}" << endl; // end function + f_gen_ << indent() << "}" << '\n'; // end function } void t_rs_generator::render_sync_handler_succeeded(t_function* tfunc) { if (tfunc->is_oneway()) { - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { f_gen_ << indent() << "let message_ident = TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Reply, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; - f_gen_ << indent() << "let ret = " << handler_successful_return_struct(tfunc) << ";" << endl; - f_gen_ << indent() << "ret.write_to_out_protocol(o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; + f_gen_ << indent() << "let ret = " << handler_successful_return_struct(tfunc) << ";" << '\n'; + f_gen_ << indent() << "ret.write_to_out_protocol(o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; } } void t_rs_generator::render_sync_handler_failed(t_function* tfunc) { string err_var("e"); - f_gen_ << indent() << "match " << err_var << " {" << endl; + f_gen_ << indent() << "match " << err_var << " {" << '\n'; indent_up(); // if there are any user-defined exceptions for this service call handle them first if (tfunc->get_xceptions() != nullptr && tfunc->get_xceptions()->get_sorted_members().size() > 0) { string user_err_var("usr_err"); - f_gen_ << indent() << "thrift::Error::User(" << user_err_var << ") => {" << endl; + f_gen_ << indent() << "thrift::Error::User(" << user_err_var << ") => {" << '\n'; indent_up(); render_sync_handler_failed_user_exception_branch(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // application error string app_err_var("app_err"); - f_gen_ << indent() << "thrift::Error::Application(" << app_err_var << ") => {" << endl; + f_gen_ << indent() << "thrift::Error::Application(" << app_err_var << ") => {" << '\n'; indent_up(); render_sync_handler_failed_application_exception_branch(tfunc, app_err_var); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; // default case - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); render_sync_handler_failed_default_exception_branch(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function* tfunc) { @@ -2670,11 +2679,11 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function string if_statement(branches_rendered == 0 ? "if usr_err" : "} else if usr_err"); string exception_type(to_rust_type(xception_field->get_type())); f_gen_ << indent() << if_statement << ".downcast_ref::<" << exception_type << ">().is_some() {" - << endl; + << '\n'; indent_up(); f_gen_ << indent() << "let err = usr_err.downcast::<" << exception_type - << ">().expect(\"downcast already checked\");" << endl; + << ">().expect(\"downcast already checked\");" << '\n'; // render the members of the return struct ostringstream members; @@ -2701,17 +2710,17 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function // now write out the return struct f_gen_ << indent() << "let ret_err = " << service_call_result_struct_name(tfunc) << "{ " - << member_string << "};" << endl; + << member_string << "};" << '\n'; f_gen_ << indent() << "let message_ident = " << "TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Reply, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; - f_gen_ << indent() << "ret_err.write_to_out_protocol(o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; + f_gen_ << indent() << "ret_err.write_to_out_protocol(o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; indent_down(); @@ -2719,41 +2728,41 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function } // the catch all, if somehow it was a user exception that we don't support - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); // FIXME: same as default block below - f_gen_ << indent() << "let ret_err = {" << endl; + f_gen_ << indent() << "let ret_err = {" << '\n'; indent_up(); render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "usr_err.to_string()"); indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; render_sync_handler_send_exception_response(tfunc, "ret_err"); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_handler_failed_application_exception_branch( t_function* tfunc, const string& app_err_var) { if (tfunc->is_oneway()) { - f_gen_ << indent() << "Err(thrift::Error::Application(" << app_err_var << "))" << endl; + f_gen_ << indent() << "Err(thrift::Error::Application(" << app_err_var << "))" << '\n'; } else { render_sync_handler_send_exception_response(tfunc, app_err_var); } } void t_rs_generator::render_sync_handler_failed_default_exception_branch(t_function* tfunc) { - f_gen_ << indent() << "let ret_err = {" << endl; + f_gen_ << indent() << "let ret_err = {" << '\n'; indent_up(); render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "e.to_string()"); indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; if (tfunc->is_oneway()) { - f_gen_ << indent() << "Err(thrift::Error::Application(ret_err))" << endl; + f_gen_ << indent() << "Err(thrift::Error::Application(ret_err))" << '\n'; } else { render_sync_handler_send_exception_response(tfunc, "ret_err"); } @@ -2764,12 +2773,12 @@ void t_rs_generator::render_sync_handler_send_exception_response(t_function* tfu f_gen_ << indent() << "let message_ident = TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Exception, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; f_gen_ << indent() << "thrift::Error::write_application_error_to_out_protocol(&" << err_var - << ", o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << ", o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; } string t_rs_generator::handler_successful_return_struct(t_function* tfunc) { @@ -2811,10 +2820,10 @@ string t_rs_generator::handler_successful_return_struct(t_function* tfunc) { //----------------------------------------------------------------------------- void t_rs_generator::render_type_comment(const string& type_name) { - f_gen_ << "//" << endl; - f_gen_ << "// " << type_name << endl; - f_gen_ << "//" << endl; - f_gen_ << endl; + f_gen_ << "//" << '\n'; + f_gen_ << "// " << type_name << '\n'; + f_gen_ << "//" << '\n'; + f_gen_ << '\n'; } // NOTE: do *not* put in an extra newline after doc is generated. @@ -2831,26 +2840,26 @@ void t_rs_generator::render_thrift_error(const string& error_kind, const string& error_struct, const string& sub_error_kind, const string& error_message) { - f_gen_ << indent() << "Err(" << endl; + f_gen_ << indent() << "Err(" << '\n'; indent_up(); - f_gen_ << indent() << "thrift::Error::" << error_kind << "(" << endl; + f_gen_ << indent() << "thrift::Error::" << error_kind << "(" << '\n'; indent_up(); render_thrift_error_struct(error_struct, sub_error_kind, error_message); indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; } void t_rs_generator::render_thrift_error_struct(const string& error_struct, const string& sub_error_kind, const string& error_message) { - f_gen_ << indent() << error_struct << "::new(" << endl; + f_gen_ << indent() << error_struct << "::new(" << '\n'; indent_up(); - f_gen_ << indent() << sub_error_kind << "," << endl; - f_gen_ << indent() << error_message << endl; + f_gen_ << indent() << sub_error_kind << "," << '\n'; + f_gen_ << indent() << error_message << '\n'; indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; } bool t_rs_generator::is_double(t_type* ttype) { diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc index b1411867124..c1ad35577e8 100644 --- a/compiler/cpp/src/thrift/generate/t_st_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc @@ -43,8 +43,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Smalltalk code generator. * @@ -177,7 +175,7 @@ void t_st_generator::init_generator() { f_.open(f_name.c_str()); // Print header - f_ << st_autogen_comment() << endl; + f_ << st_autogen_comment() << '\n'; st_class_def(f_, program_name_); generate_class_side_definition(); @@ -219,10 +217,10 @@ string t_st_generator::st_autogen_comment() { void t_st_generator::generate_force_consts() { f_ << prefix(class_name()) << " enums keysAndValuesDo: [:k :v | " << prefix(class_name()) - << " enums at: k put: v value].!" << endl; + << " enums at: k put: v value].!" << '\n'; f_ << prefix(class_name()) << " constants keysAndValuesDo: [:k :v | " << prefix(class_name()) - << " constants at: k put: v value].!" << endl; + << " constants at: k put: v value].!" << '\n'; } void t_st_generator::close_generator() { @@ -252,11 +250,11 @@ void t_st_generator::generate_typedef(t_typedef* ttypedef) { } void t_st_generator::st_class_def(std::ostream& out, string name) { - out << "Object subclass: #" << prefix(name) << endl; + out << "Object subclass: #" << prefix(name) << '\n'; indent_up(); - out << indent() << "instanceVariableNames: ''" << endl << indent() << "classVariableNames: ''" - << endl << indent() << "poolDictionaries: ''" << endl << indent() << "category: '" - << generated_category() << "'!" << endl << endl; + out << indent() << "instanceVariableNames: ''" << '\n' << indent() << "classVariableNames: ''" + << '\n' << indent() << "poolDictionaries: ''" << '\n' << indent() << "category: '" + << generated_category() << "'!" << '\n' << '\n'; } void t_st_generator::st_method(std::ostream& out, string cls, string name) { @@ -281,14 +279,14 @@ void t_st_generator::st_method(std::ostream& out, string cls, string name, strin strftime(timestr, 50, "%m/%d/%Y %H:%M", tinfo); out << "!" << prefix(cls) << " methodsFor: '" + category + "' stamp: 'thrift " << timestr - << "'!\n" << name << endl; + << "'!\n" << name << '\n'; indent_up(); out << indent(); } void t_st_generator::st_close_method(std::ostream& out) { - out << "! !" << endl << endl; + out << "! !" << '\n' << '\n'; indent_down(); } @@ -316,16 +314,16 @@ void t_st_generator::st_accessors(std::ostream& out, } void t_st_generator::generate_class_side_definition() { - f_ << prefix(class_name()) << " class" << endl << "\tinstanceVariableNames: 'constants enums'!" - << endl << endl; + f_ << prefix(class_name()) << " class" << '\n' << "\tinstanceVariableNames: 'constants enums'!" + << '\n' << '\n'; st_accessors(f_, class_name() + " class", "enums"); st_accessors(f_, class_name() + " class", "constants"); - f_ << prefix(class_name()) << " enums: Dictionary new!" << endl; - f_ << prefix(class_name()) << " constants: Dictionary new!" << endl; + f_ << prefix(class_name()) << " enums: Dictionary new!" << '\n'; + f_ << prefix(class_name()) << " constants: Dictionary new!" << '\n'; - f_ << endl; + f_ << '\n'; } /** @@ -338,16 +336,16 @@ void t_st_generator::generate_enum(t_enum* tenum) { string cls_name = program_name_ + capitalize(tenum->get_name()); f_ << prefix(class_name()) << " enums at: '" << tenum->get_name() << "' put: [" - << "(Dictionary new " << endl; + << "(Dictionary new " << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - f_ << "\tat: '" << (*c_iter)->get_name() << "' put: " << value << ";" << endl; + f_ << "\tat: '" << (*c_iter)->get_name() << "' put: " << value << ";" << '\n'; } - f_ << "\tyourself)]!" << endl << endl; + f_ << "\tyourself)]!" << '\n' << '\n'; } /** @@ -359,7 +357,7 @@ void t_st_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); f_ << prefix(class_name()) << " constants at: '" << name << "' put: [" - << render_const_value(type, value) << "]!" << endl << endl; + << render_const_value(type, value) << "]!" << '\n' << '\n'; } /** @@ -398,7 +396,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_enum()) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << "(" << capitalize(type->get_name()) << " new " << endl; + out << "(" << capitalize(type->get_name()) << " new " << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -418,7 +416,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } out << indent() << v_iter->first->get_string() << ": " - << render_const_value(field_type, v_iter->second) << ";" << endl; + << render_const_value(field_type, v_iter->second) << ";" << '\n'; } out << indent() << "yourself)"; @@ -426,7 +424,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "(Dictionary new" << endl; + out << "(Dictionary new" << '\n'; indent_up(); indent_up(); const map& val = value->get_map(); @@ -436,7 +434,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { out << "at: " << render_const_value(ktype, v_iter->first); out << " put: "; out << render_const_value(vtype, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } out << indent() << indent() << "yourself)"; indent_down(); @@ -449,9 +447,9 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "(Set new" << endl; + out << "(Set new" << '\n'; } else { - out << "(OrderedCollection new" << endl; + out << "(OrderedCollection new" << '\n'; } indent_up(); indent_up(); @@ -460,7 +458,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent() << indent(); out << "add: " << render_const_value(etype, *v_iter); - out << ";" << endl; + out << ";" << '\n'; } out << indent() << indent() << "yourself)"; indent_down(); @@ -502,7 +500,7 @@ void t_st_generator::generate_st_struct(std::ostream& out, else out << "Object"; - out << " subclass: #" << prefix(type_name(tstruct)) << endl << "\tinstanceVariableNames: '"; + out << " subclass: #" << prefix(type_name(tstruct)) << '\n' << "\tinstanceVariableNames: '"; if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -556,7 +554,7 @@ void t_st_generator::generate_accessors(std::ostream& out, t_struct* tstruct) { camelcase((*m_iter)->get_name()), a_type((*m_iter)->get_type())); } - out << endl; + out << '\n'; } } @@ -583,17 +581,17 @@ string t_st_generator::map_writer(t_map* tmap, string fname) { out << "[oprot writeMapBegin: (TMap new keyType: " << type_to_enum(tmap->get_key_type()) << "; valueType: " << type_to_enum(tmap->get_val_type()) << "; size: " << fname << " size)." - << endl; + << '\n'; indent_up(); - out << indent() << fname << " keysAndValuesDo: [:" << key << " :" << val << " |" << endl; + out << indent() << fname << " keysAndValuesDo: [:" << key << " :" << val << " |" << '\n'; indent_up(); - out << indent() << write_val(tmap->get_key_type(), key) << "." << endl << indent() + out << indent() << write_val(tmap->get_key_type(), key) << "." << '\n' << indent() << write_val(tmap->get_val_type(), val); indent_down(); - out << "]." << endl << indent() << "oprot writeMapEnd] value"; + out << "]." << '\n' << indent() << "oprot writeMapEnd] value"; indent_down(); return out.str(); @@ -604,18 +602,18 @@ string t_st_generator::map_reader(t_map* tmap) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << endl; + out << "[|" << desc << " " << val << "| " << '\n'; indent_up(); - out << indent() << desc << " := iprot readMapBegin." << endl << indent() << val - << " := Dictionary new." << endl << indent() << desc << " size timesRepeat: [" << endl; + out << indent() << desc << " := iprot readMapBegin." << '\n' << indent() << val + << " := Dictionary new." << '\n' << indent() << desc << " size timesRepeat: [" << '\n'; indent_up(); out << indent() << val << " at: " << read_val(tmap->get_key_type()) << " put: " << read_val(tmap->get_val_type()); indent_down(); - out << "]." << endl << indent() << "iprot readMapEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readMapEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -626,16 +624,16 @@ string t_st_generator::list_writer(t_list* tlist, string fname) { string val = temp_name(); out << "[oprot writeListBegin: (TList new elemType: " << type_to_enum(tlist->get_elem_type()) - << "; size: " << fname << " size)." << endl; + << "; size: " << fname << " size)." << '\n'; indent_up(); - out << indent() << fname << " do: [:" << val << "|" << endl; + out << indent() << fname << " do: [:" << val << "|" << '\n'; indent_up(); - out << indent() << write_val(tlist->get_elem_type(), val) << endl; + out << indent() << write_val(tlist->get_elem_type(), val) << '\n'; indent_down(); - out << "]." << endl << indent() << "oprot writeListEnd] value"; + out << "]." << '\n' << indent() << "oprot writeListEnd] value"; indent_down(); return out.str(); @@ -646,17 +644,17 @@ string t_st_generator::list_reader(t_list* tlist) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << desc << " := iprot readListBegin." << endl; + out << "[|" << desc << " " << val << "| " << desc << " := iprot readListBegin." << '\n'; indent_up(); - out << indent() << val << " := OrderedCollection new." << endl << indent() << desc - << " size timesRepeat: [" << endl; + out << indent() << val << " := OrderedCollection new." << '\n' << indent() << desc + << " size timesRepeat: [" << '\n'; indent_up(); out << indent() << val << " add: " << read_val(tlist->get_elem_type()); indent_down(); - out << "]." << endl << indent() << "iprot readListEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readListEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -667,16 +665,16 @@ string t_st_generator::set_writer(t_set* tset, string fname) { string val = temp_name(); out << "[oprot writeSetBegin: (TSet new elemType: " << type_to_enum(tset->get_elem_type()) - << "; size: " << fname << " size)." << endl; + << "; size: " << fname << " size)." << '\n'; indent_up(); - out << indent() << fname << " do: [:" << val << "|" << endl; + out << indent() << fname << " do: [:" << val << "|" << '\n'; indent_up(); - out << indent() << write_val(tset->get_elem_type(), val) << endl; + out << indent() << write_val(tset->get_elem_type(), val) << '\n'; indent_down(); - out << "]." << endl << indent() << "oprot writeSetEnd] value"; + out << "]." << '\n' << indent() << "oprot writeSetEnd] value"; indent_down(); return out.str(); @@ -687,17 +685,17 @@ string t_st_generator::set_reader(t_set* tset) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << desc << " := iprot readSetBegin." << endl; + out << "[|" << desc << " " << val << "| " << desc << " := iprot readSetBegin." << '\n'; indent_up(); - out << indent() << val << " := Set new." << endl << indent() << desc << " size timesRepeat: [" - << endl; + out << indent() << val << " := Set new." << '\n' << indent() << desc << " size timesRepeat: [" + << '\n'; indent_up(); out << indent() << val << " add: " << read_val(tset->get_elem_type()); indent_down(); - out << "]." << endl << indent() << "iprot readSetEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readSetEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -709,7 +707,7 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { vector::const_iterator fld_iter; out << "[oprot writeStructBegin: " - << "(TStruct new name: '" + tstruct->get_name() + "')." << endl; + << "(TStruct new name: '" + tstruct->get_name() + "')." << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { @@ -718,15 +716,15 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { string accessor = sname + " " + camelcase(fname); if (optional) { - out << indent() << accessor << " ifNotNil: [" << endl; + out << indent() << accessor << " ifNotNil: [" << '\n'; indent_up(); } out << indent() << "oprot writeFieldBegin: (TField new name: '" << fname << "'; type: " << type_to_enum((*fld_iter)->get_type()) - << "; id: " << (*fld_iter)->get_key() << ")." << endl; + << "; id: " << (*fld_iter)->get_key() << ")." << '\n'; - out << indent() << write_val((*fld_iter)->get_type(), accessor) << "." << endl << indent() + out << indent() << write_val((*fld_iter)->get_type(), accessor) << "." << '\n' << indent() << "oprot writeFieldEnd"; if (optional) { @@ -734,7 +732,7 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { indent_down(); } - out << "." << endl; + out << "." << '\n'; } out << indent() << "oprot writeFieldStop; writeStructEnd] value"; @@ -755,33 +753,33 @@ string t_st_generator::struct_reader(t_struct* tstruct, string clsName = "") { clsName = tstruct->get_name(); } - out << "[|" << desc << " " << val << "|" << endl; + out << "[|" << desc << " " << val << "|" << '\n'; indent_up(); // This is nasty, but without it we'll break things by prefixing TResult. string name = ((capitalize(clsName) == "TResult") ? capitalize(clsName) : prefix(clsName)); - out << indent() << val << " := " << name << " new." << endl; + out << indent() << val << " := " << name << " new." << '\n'; - out << indent() << "iprot readStructBegin." << endl << indent() << "[" << desc - << " := iprot readFieldBegin." << endl << indent() << desc - << " type = TType stop] whileFalse: [|" << found << "|" << endl; + out << indent() << "iprot readStructBegin." << '\n' << indent() << "[" << desc + << " := iprot readFieldBegin." << '\n' << indent() << desc + << " type = TType stop] whileFalse: [|" << found << "|" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - out << indent() << desc << " id = " << (*fld_iter)->get_key() << " ifTrue: [" << endl; + out << indent() << desc << " id = " << (*fld_iter)->get_key() << " ifTrue: [" << '\n'; indent_up(); - out << indent() << found << " := true." << endl << indent() << val << " " + out << indent() << found << " := true." << '\n' << indent() << val << " " << camelcase((*fld_iter)->get_name()) << ": " << read_val((*fld_iter)->get_type()); indent_down(); - out << "]." << endl; + out << "]." << '\n'; } - out << indent() << found << " ifNil: [iprot skip: " << desc << " type]]." << endl; + out << indent() << found << " ifNil: [iprot skip: " << desc << " type]]." << '\n'; indent_down(); - out << indent() << "oprot readStructEnd." << endl << indent() << val << "] value"; + out << indent() << "oprot readStructEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -847,32 +845,32 @@ void t_st_generator::generate_send_method(t_function* function) { vector::const_iterator fld_iter; st_method(f_, client_class_name(), "send" + capitalize(signature)); - f_ << "oprot writeMessageBegin:" << endl; + f_ << "oprot writeMessageBegin:" << '\n'; indent_up(); - f_ << indent() << "(TCallMessage new" << endl; + f_ << indent() << "(TCallMessage new" << '\n'; indent_up(); - f_ << indent() << "name: '" << funname << "'; " << endl << indent() << "seqid: self nextSeqid)." - << endl; + f_ << indent() << "name: '" << funname << "'; " << '\n' << indent() << "seqid: self nextSeqid)." + << '\n'; indent_down(); indent_down(); f_ << indent() << "oprot writeStructBegin: " - << "(TStruct new name: '" + capitalize(camelcase(funname)) + "_args')." << endl; + << "(TStruct new name: '" + capitalize(camelcase(funname)) + "_args')." << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { string fname = camelcase((*fld_iter)->get_name()); f_ << indent() << "oprot writeFieldBegin: (TField new name: '" << fname << "'; type: " << type_to_enum((*fld_iter)->get_type()) << "; id: " << (*fld_iter)->get_key() - << ")." << endl; + << ")." << '\n'; - f_ << indent() << write_val((*fld_iter)->get_type(), fname) << "." << endl << indent() - << "oprot writeFieldEnd." << endl; + f_ << indent() << write_val((*fld_iter)->get_type(), fname) << "." << '\n' << indent() + << "oprot writeFieldEnd." << '\n'; } - f_ << indent() << "oprot writeFieldStop; writeStructEnd; writeMessageEnd." << endl; + f_ << indent() << "oprot writeFieldStop; writeStructEnd; writeMessageEnd." << '\n'; f_ << indent() << "oprot transport flush"; st_close_method(f_); @@ -897,11 +895,11 @@ void t_st_generator::generate_recv_method(t_function* function) { } st_method(f_, client_class_name(), "recv" + capitalize(funname)); - f_ << "| f msg res | " << endl << indent() << "msg := oprot readMessageBegin." << endl << indent() - << "self validateRemoteMessage: msg." << endl << indent() - << "res := " << struct_reader(&result) << "." << endl << indent() << "oprot readMessageEnd." - << endl << indent() << "oprot transport flush." << endl << indent() - << "res exception ifNotNil: [res exception signal]." << endl << indent() << "^ res"; + f_ << "| f msg res | " << '\n' << indent() << "msg := oprot readMessageBegin." << '\n' << indent() + << "self validateRemoteMessage: msg." << '\n' << indent() + << "res := " << struct_reader(&result) << "." << '\n' << indent() << "oprot readMessageEnd." + << '\n' << indent() << "oprot transport flush." << '\n' << indent() + << "res exception ifNotNil: [res exception signal]." << '\n' << indent() << "^ res"; st_close_method(f_); } @@ -940,7 +938,7 @@ void t_st_generator::generate_service_client(t_service* tservice) { extends_client = extends + "Client"; } - f_ << extends_client << " subclass: #" << prefix(client_class_name()) << endl + f_ << extends_client << " subclass: #" << prefix(client_class_name()) << '\n' << "\tinstanceVariableNames: ''\n" << "\tclassVariableNames: ''\n" << "\tpoolDictionaries: ''\n" @@ -951,11 +949,11 @@ void t_st_generator::generate_service_client(t_service* tservice) { string signature = function_signature(*f_iter); st_method(f_, client_class_name(), signature); - f_ << function_types_comment(*f_iter) << endl << indent() << "self send" - << capitalize(signature) << "." << endl; + f_ << function_types_comment(*f_iter) << '\n' << indent() << "self send" + << capitalize(signature) << "." << '\n'; if (!(*f_iter)->is_oneway()) { - f_ << indent() << "^ self recv" << capitalize(funname) << " success " << endl; + f_ << indent() << "^ self recv" << capitalize(funname) << " success " << '\n'; } st_close_method(f_); diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc index fab14135ae7..98b19ecada0 100644 --- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Swift 3 code generator. * @@ -51,7 +49,7 @@ class t_swift_generator : public t_oop_generator { const string& option_string) : t_oop_generator(program) { update_keywords_for_validation(); - + (void)option_string; map::const_iterator iter; @@ -226,14 +224,14 @@ class t_swift_generator : public t_oop_generator { private: void block_open(ostream& out) { - out << " {" << endl; + out << " {" << '\n'; indent_up(); } void block_close(ostream& out, bool end_line=true) { indent_down(); indent(out) << "}"; - if (end_line) out << endl; + if (end_line) out << '\n'; } bool field_is_optional(t_field* tfield) { @@ -320,18 +318,18 @@ void t_swift_generator::init_generator() { string f_decl_fullname = module_path + "/" + f_decl_name; f_decl_.open(f_decl_fullname.c_str()); - f_decl_ << autogen_comment() << endl; + f_decl_ << autogen_comment() << '\n'; - f_decl_ << swift_imports() << swift_thrift_imports() << endl; + f_decl_ << swift_imports() << swift_thrift_imports() << '\n'; // ...and a .swift implementation extensions file string f_impl_name = name + "+Exts.swift"; string f_impl_fullname = module_path + "/" + f_impl_name; f_impl_.open(f_impl_fullname.c_str()); - f_impl_ << autogen_comment() << endl; + f_impl_ << autogen_comment() << '\n'; - f_impl_ << swift_imports() << swift_thrift_imports() << endl; + f_impl_ << swift_imports() << swift_thrift_imports() << '\n'; } @@ -349,16 +347,16 @@ string t_swift_generator::swift_imports() { vector::const_iterator i_iter; for (i_iter=includes_list.begin(); i_iter!=includes_list.end(); ++i_iter) { - includes << "import " << *i_iter << endl; + includes << "import " << *i_iter << '\n'; } if (namespaced_) { const vector& program_includes = program_->get_includes(); for (auto program_include : program_includes) { - includes << ("import " + get_real_swift_module(program_include)) << endl; + includes << ("import " + get_real_swift_module(program_include)) << '\n'; } } - includes << endl; + includes << '\n'; return includes.str(); } @@ -381,10 +379,10 @@ string t_swift_generator::swift_thrift_imports() { vector::const_iterator i_iter; for (i_iter=includes_list.begin(); i_iter!=includes_list.end(); ++i_iter) { - includes << "import " << *i_iter << endl; + includes << "import " << *i_iter << '\n'; } - includes << endl; + includes << '\n'; return includes.str(); } @@ -395,7 +393,7 @@ string t_swift_generator::swift_thrift_imports() { void t_swift_generator::close_generator() { // stick our constants declarations at the end of the header file // since they refer to things we are defining. - f_decl_ << constants_declarations_ << endl; + f_decl_ << constants_declarations_ << '\n'; } /** @@ -405,8 +403,8 @@ void t_swift_generator::close_generator() { */ void t_swift_generator::generate_typedef(t_typedef* ttypedef) { f_decl_ << indent() << "public typealias " << ttypedef->get_symbolic() - << " = " << type_name(ttypedef->get_type()) << endl; - f_decl_ << endl; + << " = " << type_name(ttypedef->get_type()) << '\n'; + f_decl_ << '\n'; } @@ -430,80 +428,80 @@ void t_swift_generator::generate_enum(t_enum* tenum) { vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { - f_decl_ << indent() << "case " << enum_case_name((*c_iter), true) << endl; + f_decl_ << indent() << "case " << enum_case_name((*c_iter), true) << '\n'; } // unknown associated value case for safety and similar behavior to other languages if (safe_enums_) { - f_decl_ << indent() << "case unknown(Int32)" << endl; + f_decl_ << indent() << "case unknown(Int32)" << '\n'; } - f_decl_ << endl; + f_decl_ << '\n'; // TSerializable read(from:) f_decl_ << indent() << "public static func read(from proto: TProtocol) throws -> " << tenum->get_name(); block_open(f_decl_); - f_decl_ << indent() << "let raw: Int32 = try proto.read()" << endl; - f_decl_ << indent() << "let new = " << tenum->get_name() << "(rawValue: raw)" << endl; + f_decl_ << indent() << "let raw: Int32 = try proto.read()" << '\n'; + f_decl_ << indent() << "let new = " << tenum->get_name() << "(rawValue: raw)" << '\n'; - f_decl_ << indent() << "if let unwrapped = new {" << endl; + f_decl_ << indent() << "if let unwrapped = new {" << '\n'; indent_up(); - f_decl_ << indent() << "return unwrapped" << endl; + f_decl_ << indent() << "return unwrapped" << '\n'; indent_down(); - f_decl_ << indent() << "} else {" << endl; + f_decl_ << indent() << "} else {" << '\n'; indent_up(); - f_decl_ << indent() << "throw TProtocolError(error: .invalidData," << endl; + f_decl_ << indent() << "throw TProtocolError(error: .invalidData," << '\n'; f_decl_ << indent() << " message: \"Invalid enum value (\\(raw)) for \\(" - << tenum->get_name() << ".self)\")" << endl; + << tenum->get_name() << ".self)\")" << '\n'; indent_down(); - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); // empty init for TSerializable - f_decl_ << endl; + f_decl_ << '\n'; f_decl_ << indent() << "public init()"; block_open(f_decl_); - f_decl_ << indent() << "self = ." << enum_case_name(constants.front(), false) << endl; + f_decl_ << indent() << "self = ." << enum_case_name(constants.front(), false) << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; // rawValue getter f_decl_ << indent() << "public var rawValue: Int32"; block_open(f_decl_); - f_decl_ << indent() << "switch self {" << endl; + f_decl_ << indent() << "switch self {" << '\n'; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case ." << enum_case_name((*c_iter), true) - << ": return " << (*c_iter)->get_value() << endl; + << ": return " << (*c_iter)->get_value() << '\n'; } if (safe_enums_) { - f_decl_ << indent() << "case .unknown(let value): return value" << endl; + f_decl_ << indent() << "case .unknown(let value): return value" << '\n'; } - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; // convenience rawValue initalizer f_decl_ << indent() << "public init?(rawValue: Int32)"; block_open(f_decl_); - f_decl_ << indent() << "switch rawValue {" << endl;; + f_decl_ << indent() << "switch rawValue {" << '\n';; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case " << (*c_iter)->get_value() - << ": self = ." << enum_case_name((*c_iter), true) << endl; + << ": self = ." << enum_case_name((*c_iter), true) << '\n'; } if (!safe_enums_) { - f_decl_ << indent() << "default: return nil" << endl; + f_decl_ << indent() << "default: return nil" << '\n'; } else { - f_decl_ << indent() << "default: self = .unknown(rawValue)" << endl; + f_decl_ << indent() << "default: self = .unknown(rawValue)" << '\n'; } - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; } /** @@ -521,36 +519,36 @@ void t_swift_generator::generate_old_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case " << (*c_iter)->get_name() - << " = " << (*c_iter)->get_value() << endl; + << " = " << (*c_iter)->get_value() << '\n'; } - f_decl_ << endl; - f_decl_ << indent() << "public init() { self.init(rawValue: " << constants.front()->get_value() << ")! }" << endl; + f_decl_ << '\n'; + f_decl_ << indent() << "public init() { self.init(rawValue: " << constants.front()->get_value() << ")! }" << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; f_impl_ << indent() << "extension " << tenum->get_name() << " : TEnum"; block_open(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; f_impl_ << indent() << "public static func readValueFromProtocol(proto: TProtocol) throws -> " << tenum->get_name(); block_open(f_impl_); - f_impl_ << indent() << "var raw = Int32()" << endl - << indent() << "try proto.readI32(&raw)" << endl - << indent() << "return " << tenum->get_name() << "(rawValue: raw)!" << endl; + f_impl_ << indent() << "var raw = Int32()" << '\n' + << indent() << "try proto.readI32(&raw)" << '\n' + << indent() << "return " << tenum->get_name() << "(rawValue: raw)!" << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; f_impl_ << indent() << "public static func writeValue(value: " << tenum->get_name() << ", toProtocol proto: TProtocol) throws"; block_open(f_impl_); - f_impl_ << indent() << "try proto.writeI32(value.rawValue)" << endl; + f_impl_ << indent() << "try proto.writeI32(value.rawValue)" << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; } string t_swift_generator::enum_case_name(t_enum_value* tenum_case, bool declaration) { @@ -593,7 +591,7 @@ void t_swift_generator::generate_consts(vector consts) { t_type* type = (*c_iter)->get_type(); const_interface << "public let " << capitalize((*c_iter)->get_name()) << " : " << type_name(type) << " = "; render_const_value(const_interface, type, (*c_iter)->get_value()); - const_interface << endl << endl; + const_interface << '\n' << '\n'; } // this gets spit into the header file in ::close_generator @@ -647,7 +645,7 @@ void t_swift_generator::generate_docstring(ostream& out, string& doc) { vector::const_iterator d_iter; for (d_iter = strings.begin(); d_iter != strings.end(); ++d_iter) { if ((*d_iter) != "") { - out << indent() << "/// " << (*d_iter) << endl; + out << indent() << "/// " << (*d_iter) << '\n'; } } } @@ -685,12 +683,12 @@ void t_swift_generator::generate_swift_struct(ostream& out, out << indent() << "public enum " << tstruct->get_name(); block_open(out); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; string doc = (*m_iter)->get_doc(); generate_docstring(out, doc); out << indent() << "case " << maybe_escape_identifier((*m_iter)->get_name()) << "(val: " - << type_name((*m_iter)->get_type(), false) << ")" << endl; + << type_name((*m_iter)->get_type(), false) << ")" << '\n'; } } else { // Normal structs @@ -707,20 +705,20 @@ void t_swift_generator::generate_swift_struct(ostream& out, vector sorted = members; sort(sorted.begin(), sorted.end(), [](t_field *a, t_field *b) { return (a->get_key() < b->get_key()); } ); for (m_iter = sorted.begin(); m_iter != sorted.end(); ++m_iter) { - out << endl; + out << '\n'; // TODO: Defaults string doc = (*m_iter)->get_doc(); generate_docstring(out, doc); - out << indent() << declare_property(*m_iter, is_private) << endl; + out << indent() << declare_property(*m_iter, is_private) << '\n'; } - out << endl; - out << endl; + out << '\n'; + out << '\n'; if (!struct_has_required_fields(tstruct)) { - indent(out) << visibility << " init() { }" << endl; + indent(out) << visibility << " init() { }" << '\n'; } if (struct_has_required_fields(tstruct)) { generate_swift_struct_init(out, tstruct, false, is_private); @@ -732,7 +730,7 @@ void t_swift_generator::generate_swift_struct(ostream& out, block_close(out); - out << endl; + out << '\n'; } /** @@ -761,11 +759,11 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; - out << indent() << declare_property(*m_iter, is_private) << endl; + out << '\n'; + out << indent() << declare_property(*m_iter, is_private) << '\n'; } - out << endl; + out << '\n'; // init @@ -773,7 +771,7 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, block_open(out); block_close(out); - out << endl; + out << '\n'; if (struct_has_required_fields(tstruct)) { generate_swift_struct_init(out, tstruct, false, is_private); @@ -784,7 +782,7 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, block_close(out); - out << endl; + out << '\n'; } /** @@ -831,20 +829,20 @@ void t_swift_generator::generate_swift_struct_init(ostream& out, should_set = should_set || !field_is_optional((*m_iter)); if (should_set) { out << indent() << "self." << maybe_escape_identifier((*m_iter)->get_name()) << " = " - << maybe_escape_identifier((*m_iter)->get_name()) << endl; + << maybe_escape_identifier((*m_iter)->get_name()) << '\n'; } } else { /** legacy Swift2/Cocoa */ if (all || (*m_iter)->get_req() == t_field::T_REQUIRED || (*m_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { out << indent() << "self." << maybe_escape_identifier((*m_iter)->get_name()) << " = " - << maybe_escape_identifier((*m_iter)->get_name()) << endl; + << maybe_escape_identifier((*m_iter)->get_name()) << '\n'; } } } block_close(out); - out << endl; + out << '\n'; } /** @@ -861,7 +859,7 @@ void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out, string visibility = is_private ? (gen_cocoa_ ? "private" : "fileprivate") : "public"; indent(out) << "extension " << tstruct->get_name() << " : Hashable"; block_open(out); - out << endl; + out << '\n'; indent(out) << visibility << " func hash(into hasher: inout Hasher)"; block_open(out); @@ -872,21 +870,21 @@ void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out, if (!tstruct->is_union()) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* tfield = *m_iter; - indent(out) << "hasher.combine(" << maybe_escape_identifier(tfield->get_name()) << ")" << endl; + indent(out) << "hasher.combine(" << maybe_escape_identifier(tfield->get_name()) << ")" << '\n'; } } else { - indent(out) << "switch self {" << endl; + indent(out) << "switch self {" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); m_iter++) { t_field *tfield = *m_iter; - indent(out) << "case ." << tfield->get_name() << "(let val): hasher.combine(val)" << endl; + indent(out) << "case ." << tfield->get_name() << "(let val): hasher.combine(val)" << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -912,7 +910,7 @@ void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out, if (members.size()) { if (!tstruct->is_union()) { - out << endl; + out << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end();) { @@ -922,30 +920,30 @@ void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out, if (++m_iter != members.end()) { out << " &&"; } - out << endl; + out << '\n'; } indent_down(); } else { block_open(out); - indent(out) << "switch (lhs, rhs) {" << endl; + indent(out) << "switch (lhs, rhs) {" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* tfield = *m_iter; indent(out) << "case (." << tfield->get_name() << "(let lval), ." << tfield->get_name() << "(let rval)): return lval == rval" - << endl; + << '\n'; } - indent(out) << "default: return false" << endl; - indent(out) << "}" << endl; + indent(out) << "default: return false" << '\n'; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}()" << endl; + indent(out) << "}()" << '\n'; } } else { - out << " true" << endl; + out << " true" << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -972,7 +970,7 @@ void t_swift_generator::generate_swift_struct_implementation(ostream& out, generate_swift_struct_hashable_extension(out, tstruct, is_private); generate_swift_struct_thrift_extension(out, tstruct, is_result, is_private); - out << endl << endl; + out << '\n' << '\n'; } /** @@ -993,7 +991,7 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, block_open(out); - out << endl; + out << '\n'; if (!gen_cocoa_) { /** Swift 3, no writer we just write field ID's */ string access = (is_private) ? (gen_cocoa_ ? "private" : "fileprivate") : "public"; @@ -1012,11 +1010,11 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, // pad a colon out << ":"; } - out << "]" << endl; + out << "]" << '\n'; block_close(out); - out << endl; + out << '\n'; out << indent() << access << " static var structName: String { return \"" - << tstruct->get_name() << "\" }" << endl << endl; + << tstruct->get_name() << "\" }" << '\n' << '\n'; if (tstruct->is_union()) { generate_swift_union_reader(out, tstruct); @@ -1037,24 +1035,24 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, } block_close(out); - out << endl; + out << '\n'; } void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstruct) { indent(out) << "public static func read(from proto: TProtocol) throws -> " << tstruct->get_name(); block_open(out); - indent(out) << "_ = try proto.readStructBegin()" << endl; + indent(out) << "_ = try proto.readStructBegin()" << '\n'; indent(out) << "var ret: " << tstruct->get_name() << "?"; - out << endl; + out << '\n'; indent(out) << "fields: while true"; block_open(out); - out << endl; - indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << endl << endl; + out << '\n'; + indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .stop): break fields" << endl; + indent(out) << "case (_, .stop): break fields" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1094,28 +1092,28 @@ void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstr indent(out) << padding << "ret = " << tstruct->get_name() << "." << (*f_iter)->get_name() << "(val: " << "try " << type_name((*f_iter)->get_type(), false, false) - << ".read(from: proto))" << endl; + << ".read(from: proto))" << '\n'; } - indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << endl; + indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << '\n'; block_close(out); - indent(out) << "try proto.readFieldEnd()" << endl; + indent(out) << "try proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; - indent(out) << "try proto.readStructEnd()" << endl; + indent(out) << "try proto.readStructEnd()" << '\n'; indent(out) << "if let ret = ret"; block_open(out); - indent(out) << "return ret" << endl; + indent(out) << "return ret" << '\n'; block_close(out); - out << endl; + out << '\n'; indent(out) << "throw TProtocolError(error: .unknown, message: \"Missing required value for type: " << tstruct->get_name() << "\")"; block_close(out); - out << endl; + out << '\n'; } @@ -1139,7 +1137,7 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, << tstruct->get_name(); block_open(out); - indent(out) << "_ = try proto.readStructBegin()" << endl; + indent(out) << "_ = try proto.readStructBegin()" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1147,20 +1145,20 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool optional = field_is_optional(*f_iter); indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << ": " - << type_name((*f_iter)->get_type(), optional, !optional) << endl; + << type_name((*f_iter)->get_type(), optional, !optional) << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields indent(out) << "fields: while true"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << endl << endl; + indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .stop): break fields" << endl; + indent(out) << "case (_, .stop): break fields" << '\n'; // Generate deserialization code for known cases @@ -1198,33 +1196,33 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, } out << padding << maybe_escape_identifier((*f_iter)->get_name()) << " = try " - << type_name((*f_iter)->get_type(), false, false) << ".read(from: proto)" << endl; + << type_name((*f_iter)->get_type(), false, false) << ".read(from: proto)" << '\n'; } - indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << endl; + indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << '\n'; block_close(out); - out << endl; + out << '\n'; // Read field end marker - indent(out) << "try proto.readFieldEnd()" << endl; + indent(out) << "try proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; - indent(out) << "try proto.readStructEnd()" << endl; + out << '\n'; + indent(out) << "try proto.readStructEnd()" << '\n'; if (struct_has_required_fields(tstruct)) { // performs various checks (e.g. check that all required fields are set) - indent(out) << "// Required fields" << endl; + indent(out) << "// Required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (field_is_optional(*f_iter)) { continue; } indent(out) << "try proto.validateValue(" << maybe_escape_identifier((*f_iter)->get_name()) << ", " - << "named: \"" << (*f_iter)->get_name() << "\")" << endl; + << "named: \"" << (*f_iter)->get_name() << "\")" << '\n'; } } - out << endl; + out << '\n'; indent(out) << "return " << tstruct->get_name() << "("; for (f_iter = fields.begin(); f_iter != fields.end();) { @@ -1242,8 +1240,8 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, << tstruct->get_name(); block_open(out); - out << endl; - indent(out) << "try __proto.readStructBegin()" << endl << endl; + out << '\n'; + indent(out) << "try __proto.readStructBegin()" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1251,66 +1249,66 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool optional = field_is_optional(*f_iter); indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << " : " - << type_name((*f_iter)->get_type(), optional, !optional) << endl; + << type_name((*f_iter)->get_type(), optional, !optional) << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields indent(out) << "fields: while true"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let (_, fieldType, fieldID) = try __proto.readFieldBegin()" << endl << endl; + indent(out) << "let (_, fieldType, fieldID) = try __proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .STOP):" << endl; + indent(out) << "case (_, .STOP):" << '\n'; indent_up(); - indent(out) << "break fields" << endl << endl; + indent(out) << "break fields" << '\n' << '\n'; indent_down(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):" << endl; + indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):" << '\n'; indent_up(); indent(out) << maybe_escape_identifier((*f_iter)->get_name()) << " = try __proto.readValue() as " - << type_name((*f_iter)->get_type()) << endl << endl; + << type_name((*f_iter)->get_type()) << '\n' << '\n'; indent_down(); } - indent(out) << "case let (_, unknownType):" << endl; + indent(out) << "case let (_, unknownType):" << '\n'; indent_up(); - indent(out) << "try __proto.skipType(unknownType)" << endl; + indent(out) << "try __proto.skipType(unknownType)" << '\n'; indent_down(); block_close(out); - out << endl; + out << '\n'; // Read field end marker - indent(out) << "try __proto.readFieldEnd()" << endl; + indent(out) << "try __proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; - indent(out) << "try __proto.readStructEnd()" << endl; - out << endl; + out << '\n'; + indent(out) << "try __proto.readStructEnd()" << '\n'; + out << '\n'; if (struct_has_required_fields(tstruct)) { // performs various checks (e.g. check that all required fields are set) - indent(out) << "// Required fields" << endl; + indent(out) << "// Required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (field_is_optional(*f_iter)) { continue; } indent(out) << "try __proto.validateValue(" << (*f_iter)->get_name() << ", " - << "named: \"" << (*f_iter)->get_name() << "\")" << endl; + << "named: \"" << (*f_iter)->get_name() << "\")" << '\n'; } } - out << endl; + out << '\n'; indent(out) << "return " << tstruct->get_name() << "("; for (f_iter = fields.begin(); f_iter != fields.end();) { @@ -1320,11 +1318,11 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, } } } - out << ")" << endl; + out << ")" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1344,14 +1342,14 @@ void t_swift_generator::generate_old_swift_struct_writer(ostream& out, indent(out) << visibility << " static func writeValue(__value: " << tstruct->get_name() << ", toProtocol __proto: TProtocol) throws"; block_open(out); - out << endl; + out << '\n'; string name = tstruct->get_name(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << endl; - out << endl; + indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << '\n'; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field *tfield = *f_iter; @@ -1367,19 +1365,19 @@ void t_swift_generator::generate_old_swift_struct_writer(ostream& out, << (optional ? "" : "__value.") << maybe_escape_identifier(tfield->get_name()) << ", " << "name: \"" << tfield->get_name() << "\", " << "type: " << type_to_enum(tfield->get_type()) << ", " - << "id: " << tfield->get_key() << ")" << endl; + << "id: " << tfield->get_key() << ")" << '\n'; if (optional) { block_close(out); } - out << endl; + out << '\n'; } - indent(out) << "try __proto.writeFieldStop()" << endl << endl; - indent(out) << "try __proto.writeStructEnd()" << endl; + indent(out) << "try __proto.writeFieldStop()" << '\n' << '\n'; + indent(out) << "try __proto.writeStructEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1396,12 +1394,12 @@ void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_ indent(out) << "private static func writeValue(__value: " << tstruct->get_name() << ", toProtocol __proto: TProtocol) throws"; block_open(out); - out << endl; + out << '\n'; string name = tstruct->get_name(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << endl; - out << endl; + indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << '\n'; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field *tfield = *f_iter; @@ -1413,15 +1411,15 @@ void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_ indent(out) << "try __proto.writeFieldValue(result, " << "name: \"" << tfield->get_name() << "\", " << "type: " << type_to_enum(tfield->get_type()) << ", " - << "id: " << tfield->get_key() << ")" << endl; + << "id: " << tfield->get_key() << ")" << '\n'; block_close(out); } // Write the struct map - indent(out) << "try __proto.writeFieldStop()" << endl << endl; - indent(out) << "try __proto.writeStructEnd()" << endl; + indent(out) << "try __proto.writeFieldStop()" << '\n' << '\n'; + indent(out) << "try __proto.writeStructEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1440,50 +1438,50 @@ void t_swift_generator::generate_swift_struct_printable_extension(ostream& out, << (debug_descriptions_ ? "CustomDebugStringConvertible" : "CustomStringConvertible"); block_open(out); - out << endl; + out << '\n'; indent(out) << "public var description : String"; block_open(out); indent(out) << "var desc = \"" << tstruct->get_name(); if (!gen_cocoa_) { if (!tstruct->is_union()) { - out << "(\"" << endl; + out << "(\"" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();) { indent(out) << "desc += \"" << (*f_iter)->get_name() << "=\\(String(describing: self." << maybe_escape_identifier((*f_iter)->get_name()) << "))"; if (++f_iter != fields.end()) { out << ", "; } - out << "\"" << endl; + out << "\"" << '\n'; } } else { - out << ".\"" << endl; - indent(out) << "switch self {" << endl; + out << ".\"" << '\n'; + indent(out) << "switch self {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();f_iter++) { indent(out) << "case ." << (*f_iter)->get_name() << "(let val): " << "desc += \"" << (*f_iter)->get_name() << "(val: \\(val))\"" - << endl; + << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } else { - out << "(\"" << endl; + out << "(\"" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();) { indent(out) << "desc += \"" << (*f_iter)->get_name() << "=\\(self." << maybe_escape_identifier((*f_iter)->get_name()) << ")"; if (++f_iter != fields.end()) { out << ", "; } - out << "\"" << endl; + out << "\"" << '\n'; } - indent(out) << "desc += \")\"" << endl; + indent(out) << "desc += \")\"" << '\n'; } - indent(out) << "return desc" << endl; + indent(out) << "return desc" << '\n'; block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1606,14 +1604,14 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* out << " : " << parent->get_name(); } block_open(out); - out << endl; + out << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { function_docstring(out, *f_iter); - indent(out) << function_signature(*f_iter) << endl << endl; + indent(out) << function_signature(*f_iter) << '\n' << '\n'; } } else { @@ -1624,7 +1622,7 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - out << endl; + out << '\n'; indent(out) << function_signature(*f_iter) << " // exceptions: "; t_struct* xs = (*f_iter)->get_xceptions(); const vector& xceptions = xs->get_members(); @@ -1632,11 +1630,11 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << type_name((*x_iter)->get_type()) + ", "; } - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -1652,7 +1650,7 @@ void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_se indent(out) << "public protocol " << tservice->get_name() << "Async"; block_open(out); - if (!gen_cocoa_) { out << endl; } + if (!gen_cocoa_) { out << '\n'; } vector functions = tservice->get_functions(); vector::iterator f_iter; @@ -1660,20 +1658,20 @@ void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_se if (!gen_cocoa_) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { async_function_docstring(out, *f_iter); - indent(out) << async_function_signature(*f_iter) << endl << endl; + indent(out) << async_function_signature(*f_iter) << '\n' << '\n'; } } else { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - out << endl; - indent(out) << async_function_signature(*f_iter) << endl; + out << '\n'; + indent(out) << async_function_signature(*f_iter) << '\n'; if (promise_kit_) { - indent(out) << promise_function_signature(*f_iter) << endl; + indent(out) << promise_function_signature(*f_iter) << '\n'; } // - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -1690,33 +1688,33 @@ void t_swift_generator::generate_swift_service_client(ostream& out, t_service* t out << " : " << ((parent == nullptr) ? "TClient" : parent->get_name() + "Client"); out << " /* , " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; } else { // a indent(out) << "public class " << tservice->get_name() << "Client /* : " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let __inProtocol : TProtocol" << endl << endl; - indent(out) << "let __outProtocol : TProtocol" << endl << endl; + indent(out) << "let __inProtocol : TProtocol" << '\n' << '\n'; + indent(out) << "let __outProtocol : TProtocol" << '\n' << '\n'; indent(out) << "public init(inoutProtocol: TProtocol)"; block_open(out); - indent(out) << "__inProtocol = inoutProtocol" << endl; - indent(out) << "__outProtocol = inoutProtocol" << endl; + indent(out) << "__inProtocol = inoutProtocol" << '\n'; + indent(out) << "__outProtocol = inoutProtocol" << '\n'; block_close(out); - out << endl; + out << '\n'; indent(out) << "public init(inProtocol: TProtocol, outProtocol: TProtocol)"; block_open(out); - indent(out) << "__inProtocol = inProtocol" << endl; - indent(out) << "__outProtocol = outProtocol" << endl; + indent(out) << "__inProtocol = inProtocol" << '\n'; + indent(out) << "__outProtocol = outProtocol" << '\n'; block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1736,24 +1734,24 @@ void t_swift_generator::generate_swift_service_client_async(ostream& out, t_serv out << " /* , " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; } else { indent(out) << "public class " << tservice->get_name() << "AsyncClient /* : " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let __protocolFactory : TProtocolFactory" << endl << endl; - indent(out) << "let __transportFactory : TAsyncTransportFactory" << endl << endl; + indent(out) << "let __protocolFactory : TProtocolFactory" << '\n' << '\n'; + indent(out) << "let __transportFactory : TAsyncTransportFactory" << '\n' << '\n'; indent(out) << "public init(protocolFactory: TProtocolFactory, transportFactory: TAsyncTransportFactory)"; block_open(out); - indent(out) << "__protocolFactory = protocolFactory" << endl; - indent(out) << "__transportFactory = transportFactory" << endl; + indent(out) << "__protocolFactory = protocolFactory" << '\n'; + indent(out) << "__transportFactory = transportFactory" << '\n'; block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1767,34 +1765,34 @@ void t_swift_generator::generate_swift_service_server(ostream& out, t_service* t indent(out) << "open class " << tservice->get_name() << "Processor /* " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; out << indent() << "typealias ProcessorHandlerDictionary = " - << "[String: (Int32, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << endl - << endl - << indent() << "public var service: " << tservice->get_name() << endl - << endl + << "[String: (Int32, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << '\n' + << '\n' + << indent() << "public var service: " << tservice->get_name() << '\n' + << '\n' << indent() << "public required init(service: " << tservice->get_name() << ")"; } else { indent(out) << "public class " << tservice->get_name() << "Processor : NSObject /* " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; out << indent() << "typealias ProcessorHandlerDictionary = " - << "[String: (Int, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << endl - << endl - << indent() << "let service : " << tservice->get_name() << endl - << endl + << "[String: (Int, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << '\n' + << '\n' + << indent() << "let service : " << tservice->get_name() << '\n' + << '\n' << indent() << "public init(service: " << tservice->get_name() << ")"; } block_open(out); - indent(out) << "self.service = service" << endl; + indent(out) << "self.service = service" << '\n'; block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1831,7 +1829,7 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati // Serialize the request indent(out) << "try outProtocol.writeMessageBegin(name: \"" << funname << "\", " << "type: " << (tfunction->is_oneway() ? ".oneway" : ".call") << ", " - << "sequenceID: 0)" << endl; + << "sequenceID: 0)" << '\n'; indent(out) << "let args = " << argsname << "("; @@ -1847,18 +1845,18 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati out << ", "; } } - out << ")" << endl; - indent(out) << "try args.write(to: outProtocol)" << endl; - indent(out) << "try outProtocol.writeMessageEnd()" << endl; + out << ")" << '\n'; + indent(out) << "try args.write(to: outProtocol)" << '\n'; + indent(out) << "try outProtocol.writeMessageEnd()" << '\n'; } else { - out << endl; + out << '\n'; // Serialize the request indent(out) << "try __outProtocol.writeMessageBeginWithName(\"" << funname << "\", " << "type: " << (tfunction->is_oneway() ? ".ONEWAY" : ".CALL") << ", " - << "sequenceID: 0)" << endl; + << "sequenceID: 0)" << '\n'; - out << endl; + out << '\n'; indent(out) << "let __args = " << argsname << "("; @@ -1874,13 +1872,13 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati out << ", "; } } - out << ")" << endl; - indent(out) << "try " << argsname << ".writeValue(__args, toProtocol: __outProtocol)" << endl << endl; - indent(out) << "try __outProtocol.writeMessageEnd()" << endl; + out << ")" << '\n'; + indent(out) << "try " << argsname << ".writeValue(__args, toProtocol: __outProtocol)" << '\n' << '\n'; + indent(out) << "try __outProtocol.writeMessageEnd()" << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1913,7 +1911,7 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati // check for an exception - indent(out) << "try inProtocol.readResultMessageBegin() " << endl; + indent(out) << "try inProtocol.readResultMessageBegin() " << '\n'; string resultname = function_result_helper_struct_type(tservice, tfunction); indent(out); @@ -1924,15 +1922,15 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati } string return_type_name = type_name(tfunction->get_returntype()); - out << "try " << resultname << ".read(from: inProtocol)" << endl; + out << "try " << resultname << ".read(from: inProtocol)" << '\n'; - indent(out) << "try inProtocol.readMessageEnd()" << endl << endl; + indent(out) << "try inProtocol.readMessageEnd()" << '\n' << '\n'; // Careful, only return _result if not a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "if let success = result.success"; block_open(out); - indent(out) << "return success" << endl; + indent(out) << "return success" << '\n'; block_close(out); } @@ -1943,14 +1941,14 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent(out) << "if let " << (*x_iter)->get_name() << " = result." << (*x_iter)->get_name(); block_open(out); - indent(out) << "throw " << (*x_iter)->get_name() << endl; + indent(out) << "throw " << (*x_iter)->get_name() << '\n'; block_close(out); } // If you get here it's an exception, unless a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "throw TApplicationError(error: .missingResult(methodName: \"" - << tfunction->get_name() << "\"))" << endl; + << tfunction->get_name() << "\"))" << '\n'; } } else { if (needs_protocol) { @@ -1966,22 +1964,22 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati block_open(out); // check for an exception - out << endl; - indent(out) << "try __inProtocol.readResultMessageBegin() " << endl << endl; + out << '\n'; + indent(out) << "try __inProtocol.readResultMessageBegin() " << '\n' << '\n'; string resultname = function_result_helper_struct_type(tservice, tfunction); indent(out); if (!tfunction->get_returntype()->is_void() || !tfunction->get_xceptions()->get_members().empty()) { out << "let __result = "; } - out << "try " << resultname << ".readValueFromProtocol(__inProtocol)" << endl << endl; + out << "try " << resultname << ".readValueFromProtocol(__inProtocol)" << '\n' << '\n'; - indent(out) << "try __inProtocol.readMessageEnd()" << endl << endl; + indent(out) << "try __inProtocol.readMessageEnd()" << '\n' << '\n'; // Careful, only return _result if not a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "if let __success = __result.success"; block_open(out); - indent(out) << "return __success" << endl; + indent(out) << "return __success" << '\n'; block_close(out); } @@ -1992,24 +1990,24 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent(out) << "if let " << (*x_iter)->get_name() << " = __result." << (*x_iter)->get_name(); block_open(out); - indent(out) << "throw " << (*x_iter)->get_name() << endl; + indent(out) << "throw " << (*x_iter)->get_name() << '\n'; block_close(out); } // If you get here it's an exception, unless a void function if (!tfunction->get_returntype()->is_void()) { - indent(out) << "throw NSError(" << endl; + indent(out) << "throw NSError(" << '\n'; indent_up(); - indent(out) << "domain: TApplicationErrorDomain, " << endl; - indent(out) << "code: Int(TApplicationError.MissingResult.rawValue)," << endl; - indent(out) << "userInfo: [TApplicationErrorMethodKey: \"" << tfunction->get_name() << "\"])" << endl; + indent(out) << "domain: TApplicationErrorDomain, " << '\n'; + indent(out) << "code: Int(TApplicationError.MissingResult.rawValue)," << '\n'; + indent(out) << "userInfo: [TApplicationErrorMethodKey: \"" << tfunction->get_name() << "\"])" << '\n'; indent_down(); } } // Close function block_close(out); - out << endl; + out << '\n'; } /** @@ -2035,7 +2033,7 @@ void t_swift_generator::generate_swift_service_client_send_function_invocation(o } } - out << ")" << endl; + out << ")" << '\n'; } /** @@ -2061,7 +2059,7 @@ void t_swift_generator::generate_swift_service_client_send_async_function_invoca out << ", " << (*f_iter)->get_name() << ": " << (*f_iter)->get_name(); } - out << ")" << endl; + out << ")" << '\n'; } /** @@ -2075,7 +2073,7 @@ void t_swift_generator::generate_swift_service_client_implementation(ostream& ou string name = tservice->get_name() + "Client"; indent(out) << "extension " << name << " : " << tservice->get_name(); block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2092,28 +2090,28 @@ void t_swift_generator::generate_swift_service_client_implementation(ostream& ou indent(out) << "public " << function_signature(*f_iter); block_open(out); - if (gen_cocoa_) { out << endl; } + if (gen_cocoa_) { out << '\n'; } generate_swift_service_client_send_function_invocation(out, *f_iter); if (!gen_cocoa_) { - indent(out) << "try outProtocol.transport.flush()" << endl; + indent(out) << "try outProtocol.transport.flush()" << '\n'; } else { - out << endl; - indent(out) << "try __outProtocol.transport().flush()" << endl << endl; + out << '\n'; + indent(out) << "try __outProtocol.transport().flush()" << '\n' << '\n'; } if (!(*f_iter)->is_oneway()) { if ((*f_iter)->get_returntype()->is_void()) { - indent(out) << "try recv_" << (*f_iter)->get_name() << "()" << endl; + indent(out) << "try recv_" << (*f_iter)->get_name() << "()" << '\n'; } else { - indent(out) << "return try recv_" << (*f_iter)->get_name() << "()" << endl; + indent(out) << "return try recv_" << (*f_iter)->get_name() << "()" << '\n'; } } block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -2131,7 +2129,7 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre indent(out) << "extension " << name << " : " << protocol_name; block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2146,10 +2144,10 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre indent(out) << "public " << async_function_signature(*f_iter); block_open(out); - out << endl; - out << indent() << "let transport = factory.newTransport()" << endl - << indent() << "let proto = Protocol(on: transport)" << endl - << endl; + out << '\n'; + out << indent() << "let transport = factory.newTransport()" << '\n' + << indent() << "let proto = Protocol(on: transport)" << '\n' + << '\n'; out << indent() << "do"; block_open(out); @@ -2157,12 +2155,12 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre generate_swift_service_client_send_async_function_invocation(out, *f_iter); indent_down(); - out << indent() << "} catch let error {" << endl; + out << indent() << "} catch let error {" << '\n'; indent_up(); - out << indent() << "completion(.error(error))" << endl; + out << indent() << "completion(.error(error))" << '\n'; block_close(out); - out << endl; + out << '\n'; bool ret_is_void = (*f_iter)->get_returntype()->is_void(); bool is_oneway = (*f_iter)->is_oneway(); @@ -2170,10 +2168,10 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre string error_completion_call = "completion(.error(error))"; indent(out) << "transport.flush"; block_open(out); - out << indent() << "(trans, error) in" << endl << endl; + out << indent() << "(trans, error) in" << '\n' << '\n'; out << indent() << "if let error = error"; block_open(out); - out << indent() << error_completion_call << endl; + out << indent() << error_completion_call << '\n'; block_close(out); if (!is_oneway) { @@ -2183,24 +2181,24 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre if (!ret_is_void) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(on: proto)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(on: proto)" << '\n'; - out << indent() << (ret_is_void ? "completion(.success(Void()))" : "completion(.success(result))") << endl; + out << indent() << (ret_is_void ? "completion(.success(Void()))" : "completion(.success(result))") << '\n'; indent_down(); - out << indent() << "} catch let error {" << endl; + out << indent() << "} catch let error {" << '\n'; indent_up(); - out << indent() << error_completion_call << endl; + out << indent() << error_completion_call << '\n'; block_close(out); } else { - out << indent() << "completion(.success(Void()))" << endl; + out << indent() << "completion(.success(Void()))" << '\n'; } block_close(out); block_close(out); } block_close(out); - out << endl; + out << '\n'; } void t_swift_generator::generate_old_swift_service_client_async_implementation(ostream& out, @@ -2211,7 +2209,7 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "extension " << name << " : " << protocol_name; block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2226,19 +2224,19 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "public " << async_function_signature(*f_iter); block_open(out); - out << endl; + out << '\n'; - out << indent() << "let __transport = __transportFactory.newTransport()" << endl - << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << endl - << endl; + out << indent() << "let __transport = __transportFactory.newTransport()" << '\n' + << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << '\n' + << '\n'; generate_swift_service_client_send_async_function_invocation(out, *f_iter); - out << endl; + out << '\n'; indent(out) << "__transport.flushWithCompletion("; if ((*f_iter)->is_oneway()) { - out << "success, failure: failure)" << endl; + out << "success, failure: failure)" << '\n'; } else { block_open(out); @@ -2249,25 +2247,25 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o if (!(*f_iter)->get_returntype()->is_void()) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << '\n'; out << indent() << "success("; if (!(*f_iter)->get_returntype()->is_void()) { out << "result"; } - out << ")" << endl; + out << ")" << '\n'; block_close(out); indent(out) << "catch let error"; block_open(out); - indent(out) << "failure(error as NSError)" << endl; + indent(out) << "failure(error as NSError)" << '\n'; block_close(out); block_close(out); - indent(out) << ", failure: failure)" << endl; + indent(out) << ", failure: failure)" << '\n'; } block_close(out); - out << endl; + out << '\n'; // Promise function if (promise_kit_) { @@ -2275,17 +2273,17 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "public " << promise_function_signature(*f_iter); block_open(out); - out << indent() << "let (__promise, __fulfill, __reject) = Promise<" << type_name((*f_iter)->get_returntype()) << ">.pendingPromise()" << endl << endl - << indent() << "let __transport = __transportFactory.newTransport()" << endl - << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << endl - << endl; + out << indent() << "let (__promise, __fulfill, __reject) = Promise<" << type_name((*f_iter)->get_returntype()) << ">.pendingPromise()" << '\n' << '\n' + << indent() << "let __transport = __transportFactory.newTransport()" << '\n' + << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << '\n' + << '\n'; generate_swift_service_client_send_async_function_invocation(out, *f_iter); - out << endl; + out << '\n'; indent(out) << "__transport.flushWithCompletion("; if ((*f_iter)->is_oneway()) { - out << "{ __fulfill() }, failure: { __reject($0) })" << endl; + out << "{ __fulfill() }, failure: { __reject($0) })" << '\n'; } else { block_open(out); @@ -2296,37 +2294,37 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o if (!(*f_iter)->get_returntype()->is_void()) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << '\n'; out << indent() << "__fulfill("; if (!(*f_iter)->get_returntype()->is_void()) { out << "result"; } - out << ")" << endl; + out << ")" << '\n'; block_close(out); indent(out) << "catch let error"; block_open(out); - indent(out) << "__reject(error)" << endl; + indent(out) << "__reject(error)" << '\n'; block_close(out); block_close(out); - indent(out) << ", failure: { error in " << endl; + indent(out) << ", failure: { error in " << '\n'; indent_up(); - indent(out) << "__reject(error)" << endl; + indent(out) << "__reject(error)" << '\n'; indent_down(); - indent(out) << "})" << endl; + indent(out) << "})" << '\n'; } - indent(out) << "return __promise" << endl; + indent(out) << "return __promise" << '\n'; block_close(out); - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -2345,12 +2343,12 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou indent(out) << "extension " << name << " : TProcessor"; block_open(out); - out << endl; + out << '\n'; indent(out) << "static let processorHandlers" << (gen_cocoa_ ? " " : "") << ": ProcessorHandlerDictionary ="; block_open(out); - out << endl; - out << indent() << "var processorHandlers = ProcessorHandlerDictionary()" << endl << endl; + out << '\n'; + out << indent() << "var processorHandlers = ProcessorHandlerDictionary()" << '\n' << '\n'; // generate method map for routing incoming calls vector functions = tservice->get_functions(); @@ -2361,25 +2359,25 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou string args_type = function_args_helper_struct_type(tservice, *f_iter); - out << indent() << "processorHandlers[\"" << tfunction->get_name() << "\"] = { sequenceID, inProtocol, outProtocol, handler in" << endl - << endl; + out << indent() << "processorHandlers[\"" << tfunction->get_name() << "\"] = { sequenceID, inProtocol, outProtocol, handler in" << '\n' + << '\n'; indent_up(); if (!gen_cocoa_) { - out << indent() << "let args = try " << args_type << ".read(from: inProtocol)" << endl - << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << endl; + out << indent() << "let args = try " << args_type << ".read(from: inProtocol)" << '\n' + << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << '\n'; } else { - out << indent() << "let args = try " << args_type << ".readValueFromProtocol(inProtocol)" << endl - << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << endl; + out << indent() << "let args = try " << args_type << ".readValueFromProtocol(inProtocol)" << '\n' + << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << '\n'; } if (!tfunction->is_oneway() ) { string result_type = function_result_helper_struct_type(tservice, tfunction); - indent(out) << "var result = " << result_type << "()" << endl; + indent(out) << "var result = " << result_type << "()" << '\n'; indent(out) << "do"; block_open(out); @@ -2406,7 +2404,7 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } } - out << ")" << endl; + out << ")" << '\n'; block_close(out); t_struct* xs = tfunction->get_xceptions(); @@ -2423,37 +2421,37 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } out << (*x_iter)->get_type()->get_name(); - out << " { result." << (*x_iter)->get_name() << " = error }" << endl; + out << " { result." << (*x_iter)->get_name() << " = error }" << '\n'; } - indent(out) << "catch let error { throw error }" << endl; - out << endl; + indent(out) << "catch let error { throw error }" << '\n'; + out << '\n'; if (!tfunction->is_oneway()) { - out << indent() << "try outProtocol.writeMessageBegin(name: \"" << tfunction->get_name() << "\", type: .reply, sequenceID: sequenceID)" << endl - << indent() << "try result.write(to: outProtocol)" << endl - << indent() << "try outProtocol.writeMessageEnd()" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try outProtocol.writeMessageBegin(name: \"" << tfunction->get_name() << "\", type: .reply, sequenceID: sequenceID)" << '\n' + << indent() << "try result.write(to: outProtocol)" << '\n' + << indent() << "try outProtocol.writeMessageEnd()" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; } } else { for (x_iter = xfields.begin(); x_iter != xfields.end(); ++x_iter) { indent(out) << "catch let error as " << (*x_iter)->get_type()->get_name(); block_open(out); - indent(out) << "result." << (*x_iter)->get_name() << " = error" << endl; + indent(out) << "result." << (*x_iter)->get_name() << " = error" << '\n'; block_close(out); } indent(out) << "catch let error"; block_open(out); - out << indent() << "throw error" << endl; + out << indent() << "throw error" << '\n'; block_close(out); - out << endl; + out << '\n'; if (!tfunction->is_oneway()) { - out << indent() << "try outProtocol.writeMessageBeginWithName(\"" << tfunction->get_name() << "\", type: .REPLY, sequenceID: sequenceID)" << endl - << indent() << "try " << result_type << ".writeValue(result, toProtocol: outProtocol)" << endl - << indent() << "try outProtocol.writeMessageEnd()" << endl; + out << indent() << "try outProtocol.writeMessageBeginWithName(\"" << tfunction->get_name() << "\", type: .REPLY, sequenceID: sequenceID)" << '\n' + << indent() << "try " << result_type << ".writeValue(result, toProtocol: outProtocol)" << '\n' + << indent() << "try outProtocol.writeMessageEnd()" << '\n'; } } } @@ -2461,11 +2459,11 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } - indent(out) << "return processorHandlers" << endl; + indent(out) << "return processorHandlers" << '\n'; block_close(out,false); - out << "()" << endl; - out << endl; + out << "()" << '\n'; + out << '\n'; if (!gen_cocoa_) { indent(out) << "public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws"; @@ -2474,47 +2472,47 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } block_open(out); - out << endl; - out << indent() << "let (messageName, _, sequenceID) = try inProtocol.readMessageBegin()" << endl - << endl + out << '\n'; + out << indent() << "let (messageName, _, sequenceID) = try inProtocol.readMessageBegin()" << '\n' + << '\n' << indent() << "if let processorHandler = " << name << ".processorHandlers[messageName]"; block_open(out); out << indent() << "do"; block_open(out); - out << indent() << "try processorHandler(sequenceID, inProtocol, outProtocol, service)" << endl; + out << indent() << "try processorHandler(sequenceID, inProtocol, outProtocol, service)" << '\n'; block_close(out); if (!gen_cocoa_) { out << indent() << "catch let error as TApplicationError"; block_open(out); - out << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error)" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error)" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; block_close(out); block_close(out); out << indent() << "else"; block_open(out); - out << indent() << "try inProtocol.skip(type: .struct)" << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << indent() << "let ex = TApplicationError(error: .unknownMethod(methodName: messageName))" << endl - << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex)" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try inProtocol.skip(type: .struct)" << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << indent() << "let ex = TApplicationError(error: .unknownMethod(methodName: messageName))" << '\n' + << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex)" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; } else { out << indent() << "catch let error as NSError"; block_open(out); - out << indent() << "try outProtocol.writeExceptionForMessageName(messageName, sequenceID: sequenceID, ex: error)" << endl; + out << indent() << "try outProtocol.writeExceptionForMessageName(messageName, sequenceID: sequenceID, ex: error)" << '\n'; block_close(out); block_close(out); out << indent() << "else"; block_open(out); - out << indent() << "try inProtocol.skipType(.STRUCT)" << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << indent() << "try outProtocol.writeExceptionForMessageName(messageName," << endl; + out << indent() << "try inProtocol.skipType(.STRUCT)" << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << indent() << "try outProtocol.writeExceptionForMessageName(messageName," << '\n'; indent_up(); - out << indent() << "sequenceID: sequenceID," << endl - << indent() << "ex: NSError(" << endl; + out << indent() << "sequenceID: sequenceID," << '\n' + << indent() << "ex: NSError(" << '\n'; indent_up(); - out << indent() << "domain: TApplicationErrorDomain, " << endl - << indent() << "code: Int(TApplicationError.UnknownMethod.rawValue), " << endl - << indent() << "userInfo: [TApplicationErrorMethodKey: messageName]))" << endl; + out << indent() << "domain: TApplicationErrorDomain, " << '\n' + << indent() << "code: Int(TApplicationError.UnknownMethod.rawValue), " << '\n' + << indent() << "userInfo: [TApplicationErrorMethodKey: messageName]))" << '\n'; indent_down(); indent_down(); } @@ -2522,7 +2520,7 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou block_close(out); block_close(out); block_close(out); - out << endl; + out << '\n'; } /** @@ -2812,27 +2810,27 @@ void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) // Description string doc = tfunction->get_doc(); generate_docstring(out, doc); - indent(out) << "///" << endl; + indent(out) << "///" << '\n'; // Parameters const vector& fields = tfunction->get_arglist()->get_members(); vector::const_iterator f_iter; if (!fields.empty()) { - indent(out) << "/// - Parameters:" << endl; + indent(out) << "/// - Parameters:" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/// - " << (*f_iter)->get_name() << ": "; string doc = (*f_iter)->get_doc(); if (!doc.empty() && doc[doc.length()-1] == '\n') { doc.erase(doc.length()-1); } - out << doc << endl; + out << doc << '\n'; } } // Returns t_type* ttype = tfunction->get_returntype(); if (!ttype->is_void()) { - indent(out) << "/// - Returns: " << type_name(ttype) << endl; + indent(out) << "/// - Returns: " << type_name(ttype) << '\n'; } // Throws @@ -2845,7 +2843,7 @@ void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) if (*x_iter != xceptions.back()) { out << ", "; } } - out << endl; + out << '\n'; } /** @@ -2865,20 +2863,20 @@ void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunc // Description string doc = tfunction->get_doc(); generate_docstring(out, doc); - indent(out) << "///" << endl; + indent(out) << "///" << '\n'; // Parameters const vector& fields = tfunction->get_arglist()->get_members(); vector::const_iterator f_iter; if (!fields.empty()) { - indent(out) << "/// - Parameters:" << endl; + indent(out) << "/// - Parameters:" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/// - " << (*f_iter)->get_name() << ": "; string doc = (*f_iter)->get_doc(); if (!doc.empty() && doc[doc.length()-1] == '\n') { doc.erase(doc.length()-1); } - out << doc << endl; + out << doc << '\n'; } } @@ -2894,7 +2892,7 @@ void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunc out << ", "; } } - out << endl; + out << '\n'; } /** diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc index 68675cfa157..86c2718cb25 100644 --- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc @@ -39,9 +39,6 @@ using std::vector; using std::stack; using std::set; -static const string endl = "\n"; -static const string quot = "\""; - static const string default_ns_prefix = "http://thrift.apache.org/xml/ns/"; /** @@ -196,7 +193,7 @@ void t_xml_generator::write_xml_comment(string msg) { close_top_element(); // TODO: indent any EOLs that may occur with msg // TODO: proper msg escaping needed? - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; top_element_is_empty = false; } @@ -204,7 +201,7 @@ void t_xml_generator::close_top_element() { if( top_element_is_open) { top_element_is_open = false; if (elements_.size() > 0 && top_element_is_empty) { - f_xml_ << ">" << endl; + f_xml_ << ">" << '\n'; } } } @@ -224,9 +221,9 @@ void t_xml_generator::write_element_start(string name) { void t_xml_generator::write_element_end() { indent_down(); if (top_element_is_empty && top_element_is_open) { - f_xml_ << " />" << endl; + f_xml_ << " />" << '\n'; } else { - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; } top_element_is_empty = false; elements_.pop(); @@ -248,7 +245,7 @@ void t_xml_generator::write_element_string(string name, string val) { top_element_is_empty = false; f_xml_ << indent() << "<" << name << ">" << escape_xml_string(val) << "" - << endl; + << '\n'; } string t_xml_generator::escape_xml_string(const string& input) { @@ -511,7 +508,7 @@ void t_xml_generator::write_const_value(t_const_value* value) { default: indent_up(); - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; indent_down(); break; } diff --git a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc index 1f58f3a619f..8dd84f0e13c 100644 --- a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc @@ -36,8 +36,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * XSD generator, creates an XSD for the base types etc. * @@ -121,22 +119,22 @@ void t_xsd_generator::init_generator() { string f_php_name = get_out_dir() + program_->get_name() + "_xsd.php"; f_php_.open(f_php_name.c_str()); - f_php_ << "" << endl; + f_php_ << "?>" << '\n'; f_php_.close(); } void t_xsd_generator::generate_typedef(t_typedef* ttypedef) { - indent(s_xsd_types_) << "get_name() << "\">" << endl; + indent(s_xsd_types_) << "get_name() << "\">" << '\n'; indent_up(); indent(s_xsd_types_) << "get_type()) << "\" />" - << endl; + << '\n'; indent_down(); - indent(s_xsd_types_) << "" << endl << endl; + indent(s_xsd_types_) << "" << '\n' << '\n'; } void t_xsd_generator::generate_struct(t_struct* tstruct) { @@ -144,12 +142,12 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { const vector& members = tstruct->get_members(); bool xsd_all = tstruct->get_xsd_all(); - indent(s_xsd_types_) << "get_name() << "\">" << endl; + indent(s_xsd_types_) << "get_name() << "\">" << '\n'; indent_up(); if (xsd_all) { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } else { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } indent_up(); @@ -164,12 +162,12 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { indent_down(); if (xsd_all) { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } else { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } indent_down(); - indent(s_xsd_types_) << "" << endl << endl; + indent(s_xsd_types_) << "" << '\n' << '\n'; } void t_xsd_generator::generate_element(ostream& out, @@ -185,15 +183,15 @@ void t_xsd_generator::generate_element(ostream& out, string snillable = nillable ? " nillable=\"true\"" : ""; if (ttype->is_void() || ttype->is_list()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); if (attrs == nullptr && ttype->is_void()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; } else { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); if (ttype->is_list()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); string subname; t_type* subtype = ((t_list*)ttype)->get_elem_type(); @@ -203,55 +201,55 @@ void t_xsd_generator::generate_element(ostream& out, subname = type_name(subtype); } f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname - << "';" << endl; + << "';" << '\n'; generate_element(out, subname, subtype, nullptr, false, false, true); indent_down(); - indent(out) << "" << endl; - indent(out) << "" << endl; + indent(out) << "" << '\n'; + indent(out) << "" << '\n'; } if (attrs != nullptr) { const vector& members = attrs->get_members(); vector::const_iterator a_iter; for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) { indent(out) << "get_name() << "\" type=\"" - << type_name((*a_iter)->get_type()) << "\" />" << endl; + << type_name((*a_iter)->get_type()) << "\" />" << '\n'; } } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } else { if (attrs == nullptr) { indent(out) << "" - << endl; + << '\n'; } else { // Wow, all this work for a SIMPLE TYPE with attributes?!?!?! indent(out) << "" - << endl; + << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); const vector& members = attrs->get_members(); vector::const_iterator a_iter; for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) { indent(out) << "get_name() << "\" type=\"" - << type_name((*a_iter)->get_type()) << "\" />" << endl; + << type_name((*a_iter)->get_type()) << "\" />" << '\n'; } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } } } @@ -274,10 +272,10 @@ void t_xsd_generator::generate_service(t_service* tservice) { } // Print the XSD header - f_xsd_ << "" << endl - << "" << endl + f_xsd_ << "" << '\n' + << "" << '\n' << xml_autogen_comment() - << endl; + << '\n'; // Print out the type definitions indent(f_xsd_) << s_xsd_types_.str(); @@ -292,7 +290,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { string elemname = (*f_iter)->get_name() + "_response"; t_type* returntype = (*f_iter)->get_returntype(); generate_element(f_xsd_, elemname, returntype); - f_xsd_ << endl; + f_xsd_ << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -308,7 +306,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { } // Close the XSD document - f_xsd_ << endl << "" << endl; + f_xsd_ << '\n' << "" << '\n'; f_xsd_.close(); } diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc index 5177076adf7..dfd22e9a0da 100644 --- a/compiler/cpp/src/thrift/main.cc +++ b/compiler/cpp/src/thrift/main.cc @@ -373,7 +373,12 @@ string include_file(string filename) { } // Uh oh - pwarning(0, "Could not find include file %s\n", filename.c_str()); + if (g_strict >= 192) { + // On strict mode this should be failure instead of warning + failure("Could not find include file %s", filename.c_str()); + } else { + pwarning(0, "Could not find include file %s\n", filename.c_str()); + } return std::string(); } @@ -726,6 +731,8 @@ void help() { * runtime. */ void validate_const_rec(std::string name, t_type* type, t_const_value* value) { + type = type->get_true_type(); + if (type->is_void()) { throw "type error: cannot declare a void const: " + name; } diff --git a/compiler/cpp/src/thrift/parse/t_doc.h b/compiler/cpp/src/thrift/parse/t_doc.h index 0df893eb263..4033bc78d68 100644 --- a/compiler/cpp/src/thrift/parse/t_doc.h +++ b/compiler/cpp/src/thrift/parse/t_doc.h @@ -47,6 +47,8 @@ class t_doc { bool has_doc() { return has_doc_; } + virtual void validate() const { ; } + private: std::string doc_; bool has_doc_; diff --git a/compiler/cpp/src/thrift/parse/t_field.h b/compiler/cpp/src/thrift/parse/t_field.h index 928fdcf93ef..3346722646a 100644 --- a/compiler/cpp/src/thrift/parse/t_field.h +++ b/compiler/cpp/src/thrift/parse/t_field.h @@ -41,7 +41,7 @@ class t_field : public t_doc { : type_(type), name_(name), key_(0), - req_(T_OPT_IN_REQ_OUT), + req_(T_OPT_IN_REQ_OUT), value_(nullptr), xsd_optional_(false), xsd_nillable_(false), diff --git a/compiler/cpp/src/thrift/parse/t_function.h b/compiler/cpp/src/thrift/parse/t_function.h index a3b6f48e3e2..abe29039f95 100644 --- a/compiler/cpp/src/thrift/parse/t_function.h +++ b/compiler/cpp/src/thrift/parse/t_function.h @@ -83,6 +83,28 @@ class t_function : public t_doc { std::map> annotations_; + void validate() const override { + get_returntype()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if (get_returntype()->get_true_type()->is_xception()) { + failure("method %s(): exception type \"%s\" cannot be used as function return", get_name().c_str(), get_returntype()->get_name().c_str()); + } +#endif + + std::vector::const_iterator it; + std::vector list = get_arglist()->get_members(); + for(it=list.begin(); it != list.end(); ++it) { + (*it)->get_type()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( (*it)->get_type()->get_true_type()->is_xception()) { + failure("method %s(): exception type \"%s\" cannot be used as function argument %s", get_name().c_str(), (*it)->get_type()->get_name().c_str(), (*it)->get_name().c_str()); + } +#endif + } + } + private: t_type* returntype_; std::string name_; diff --git a/compiler/cpp/src/thrift/parse/t_list.h b/compiler/cpp/src/thrift/parse/t_list.h index f0b896d0cb0..9c1dfadea27 100644 --- a/compiler/cpp/src/thrift/parse/t_list.h +++ b/compiler/cpp/src/thrift/parse/t_list.h @@ -34,6 +34,14 @@ class t_list : public t_container { bool is_list() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_elem_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a list", get_elem_type()->get_name().c_str()); + } +#endif + } + private: t_type* elem_type_; }; diff --git a/compiler/cpp/src/thrift/parse/t_map.h b/compiler/cpp/src/thrift/parse/t_map.h index 9614e6849c6..6ec58cfbb13 100644 --- a/compiler/cpp/src/thrift/parse/t_map.h +++ b/compiler/cpp/src/thrift/parse/t_map.h @@ -37,6 +37,17 @@ class t_map : public t_container { bool is_map() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_key_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a map", get_key_type()->get_name().c_str()); + } + if( get_val_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a map", get_val_type()->get_name().c_str()); + } +#endif + } + private: t_type* key_type_; t_type* val_type_; diff --git a/compiler/cpp/src/thrift/parse/t_set.h b/compiler/cpp/src/thrift/parse/t_set.h index c0d4a35c190..8f7599a5a60 100644 --- a/compiler/cpp/src/thrift/parse/t_set.h +++ b/compiler/cpp/src/thrift/parse/t_set.h @@ -36,6 +36,14 @@ class t_set : public t_container { bool is_set() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_elem_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a set", get_elem_type()->get_name().c_str()); + } +#endif + } + private: t_type* elem_type_; }; diff --git a/compiler/cpp/src/thrift/parse/t_struct.h b/compiler/cpp/src/thrift/parse/t_struct.h index d990eadd57d..8b33ee6c4b3 100644 --- a/compiler/cpp/src/thrift/parse/t_struct.h +++ b/compiler/cpp/src/thrift/parse/t_struct.h @@ -112,9 +112,8 @@ class t_struct : public t_type { const members_type& get_sorted_members() const { return members_in_id_order_; } bool is_struct() const override { return !is_xception_; } - bool is_xception() const override { return is_xception_; } - + bool is_method_xcepts() const override { return is_method_xcepts_; } bool is_union() const { return is_union_; } t_field* get_field_by_name(std::string field_name) { @@ -131,6 +130,30 @@ class t_struct : public t_type { return nullptr; } + void validate() const override { + std::string what = "struct"; + if( is_union()) { + what = "union"; + } + if( is_xception()) { + what = "exception"; + } + + std::vector::const_iterator it; + std::vector list = get_members(); + for(it=list.begin(); it != list.end(); ++it) { + (*it)->get_type()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if (!is_method_xcepts_) { // this is in fact the only legal usage for any exception type + if( (*it)->get_type()->get_true_type()->is_xception()) { + failure("%s %s: exception type \"%s\" cannot be used as member field type %s", what.c_str(), get_name().c_str(), (*it)->get_type()->get_name().c_str(), (*it)->get_name().c_str()); + } + } +#endif + } + } + private: members_type members_; members_type members_in_id_order_; diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h index f4082426c8e..d087601aeca 100644 --- a/compiler/cpp/src/thrift/parse/t_type.h +++ b/compiler/cpp/src/thrift/parse/t_type.h @@ -26,6 +26,8 @@ #include #include +#define ALLOW_EXCEPTIONS_AS_TYPE + class t_program; /** @@ -54,6 +56,7 @@ class t_type : public t_doc { virtual bool is_enum() const { return false; } virtual bool is_struct() const { return false; } virtual bool is_xception() const { return false; } + virtual bool is_method_xcepts() const { return false; } virtual bool is_container() const { return false; } virtual bool is_list() const { return false; } virtual bool is_set() const { return false; } diff --git a/compiler/cpp/src/thrift/version.h b/compiler/cpp/src/thrift/version.h index 65e0f43684b..47d3a13f994 100644 --- a/compiler/cpp/src/thrift/version.h +++ b/compiler/cpp/src/thrift/version.h @@ -24,6 +24,6 @@ #pragma once #endif // _MSC_VER -#define THRIFT_VERSION "0.20.0" +#define THRIFT_VERSION "0.23.0" #endif // _THRIFT_VERSION_H_ diff --git a/compiler/cpp/test/CMakeLists.txt b/compiler/cpp/test/CMakeLists.txt index 6cf309b9d4d..beed6ea6c61 100644 --- a/compiler/cpp/test/CMakeLists.txt +++ b/compiler/cpp/test/CMakeLists.txt @@ -30,9 +30,9 @@ foreach(LANG ${KEYWORD_LANGS}) endforeach() endforeach() -find_package(PythonInterp QUIET) -if(PYTHONINTERP_FOUND) - add_test(NAME StalenessCheckTest COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER}) +find_package(Python3 COMPONENTS Interpreter QUIET) +if(Python3_Interpreter_FOUND) + add_test(NAME StalenessCheckTest COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER}) else() message(WARNING "Skipping StalenessCheckTest as there is no python interpreter available.") endif() diff --git a/compiler/cpp/test/Makefile.am b/compiler/cpp/test/Makefile.am index 10efd073767..6d4d09e938d 100644 --- a/compiler/cpp/test/Makefile.am +++ b/compiler/cpp/test/Makefile.am @@ -23,5 +23,8 @@ AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + AM_CPPFLAGS = -I$(top_srcdir)/compiler/cpp/src AM_CXXFLAGS = -Wall -Wextra -pedantic diff --git a/compiler/cpp/test/compiler/staleness_check.py b/compiler/cpp/test/compiler/staleness_check.py index 6b67798d6a4..4dcec15ce89 100755 --- a/compiler/cpp/test/compiler/staleness_check.py +++ b/compiler/cpp/test/compiler/staleness_check.py @@ -17,7 +17,6 @@ # specific language governing permissions and limitations # under the License. # -from __future__ import print_function import os import shutil import subprocess diff --git a/compiler/cpp/tests/CMakeLists.txt b/compiler/cpp/tests/CMakeLists.txt index d9c5209134c..f9908952c79 100644 --- a/compiler/cpp/tests/CMakeLists.txt +++ b/compiler/cpp/tests/CMakeLists.txt @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. # -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.16) project(thrift_compiler_tests) @@ -45,7 +45,7 @@ find_package(BISON REQUIRED) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/) # Create flex and bison files and build the lib parse static library -BISON_TARGET(thrifty ${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc) +BISON_TARGET(thrifty ${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc COMPILE_FLAGS "--file-prefix-map=${CMAKE_BINARY_DIR}='' --file-prefix-map=${CMAKE_SOURCE_DIR}=''") FLEX_TARGET(thriftl ${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/thriftl.ll ${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc) ADD_FLEX_BISON_DEPENDENCY(thriftl thrifty) diff --git a/compiler/cpp/tests/catch/catch.hpp b/compiler/cpp/tests/catch/catch.hpp index 33d037e5557..1744c742dcf 100644 --- a/compiler/cpp/tests/catch/catch.hpp +++ b/compiler/cpp/tests/catch/catch.hpp @@ -6338,7 +6338,7 @@ namespace Catch { #endif #ifdef __AFXDLL -#include +#include #else #include #endif diff --git a/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc index 6acedc0f345..348ac9faca9 100644 --- a/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc +++ b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc @@ -5,9 +5,9 @@ // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -36,7 +36,8 @@ TEST_CASE("t_netstd_generator::netstd_type_usings() without option wcf should re "using System.Threading;\n" "using System.Threading.Tasks;\n" "using Thrift;\n" - "using Thrift.Collections;\n" + endl; + "using Thrift.Collections;\n" + "\n"; t_program* program = new t_program(path, name); t_netstd_generator* gen = new t_netstd_generator(program, parsed_options, option_string); @@ -65,7 +66,8 @@ TEST_CASE("t_netstd_generator::netstd_type_usings() with option wcf should retur "using Thrift;\n" "using Thrift.Collections;\n" "using System.ServiceModel;\n" - "using System.Runtime.Serialization;\n" + endl; + "using System.Runtime.Serialization;\n" + "\n"; t_program* program = new t_program(path, name); t_netstd_generator* gen = new t_netstd_generator(program, parsed_options, option_string); diff --git a/composer.json b/composer.json index 454beeaa9fa..684c1b3875c 100644 --- a/composer.json +++ b/composer.json @@ -18,11 +18,16 @@ "issues": "https://issues.apache.org/jira/browse/THRIFT" }, "require": { - "php": "^5.5 || ^7.0 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "~4.8.36", - "squizlabs/php_codesniffer": "3.*" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "squizlabs/php_codesniffer": "3.*", + "php-mock/php-mock-phpunit": "^2.10", + "ext-json": "*", + "ext-xml": "*", + "ext-curl": "*", + "ext-pcntl": "*" }, "autoload": { "psr-4": {"Thrift\\": "lib/php/lib/"} diff --git a/configure.ac b/configure.ac index eed4a84d775..a93f7019449 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ(2.65) AC_CONFIG_MACRO_DIR([./aclocal]) -AC_INIT([thrift], [0.20.0]) +AC_INIT([thrift], [0.23.0]) AC_CONFIG_AUX_DIR([.]) @@ -95,6 +95,18 @@ AC_PROG_MKDIR_P AC_PROG_AWK AC_PROG_RANLIB +# Check if we're using Clang +AC_MSG_CHECKING([whether we are using Clang]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [[ + #ifndef __clang__ + not clang + #endif + ]])], + [CLANG=yes], [CLANG=no]) +AC_MSG_RESULT([$CLANG]) +AM_CONDITIONAL([USING_CLANG], [test "x$CLANG" = "xyes"]) + AC_LANG([C++]) AX_CXX_COMPILE_STDCXX_11([noext], [mandatory]) @@ -214,7 +226,7 @@ if test "$with_kotlin" = "yes"; then AC_PATH_PROG([GRADLE], [gradle]) AC_SUBST(CLASSPATH) AC_SUBST(GRADLE_OPTS) - if test "x$JAVA" != "x" && test "x$JAVAC" != "x" && "x$GRADLE" != "x" ; then + if test "x$JAVA" != "x" && test "x$JAVAC" != "x" && test "x$GRADLE" != "x" ; then have_kotlin="yes" fi fi @@ -761,6 +773,7 @@ AC_CONFIG_FILES([ lib/cl/Makefile lib/cpp/Makefile lib/cpp/test/Makefile + lib/cpp/test/fuzz/Makefile lib/cpp/thrift-nb.pc lib/cpp/thrift-z.pc lib/cpp/thrift-qt5.pc @@ -768,6 +781,7 @@ AC_CONFIG_FILES([ lib/c_glib/Makefile lib/c_glib/thrift_c_glib.pc lib/c_glib/test/Makefile + lib/c_glib/test/fuzz/Makefile lib/d/Makefile lib/d/test/Makefile lib/erl/Makefile @@ -793,6 +807,7 @@ AC_CONFIG_FILES([ lib/rb/Makefile lib/rs/Makefile lib/rs/test/Makefile + lib/rs/test/fuzz/Makefile lib/rs/test_recursive/Makefile lib/rs/test_recursive/src/Makefile lib/rs/test_recursive/src/maintenance/Makefile diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs index 33b0aa872c6..d45a88cdfe8 100644 --- a/contrib/Rebus/Properties/AssemblyInfo.cs +++ b/contrib/Rebus/Properties/AssemblyInfo.cs @@ -34,5 +34,5 @@ [assembly: Guid("0af10984-40d3-453d-b1e5-421529e8c7e2")] -[assembly: AssemblyVersion("0.20.0.0")] -[assembly: AssemblyFileVersion("0.20.0.0")] +[assembly: AssemblyVersion("0.23.0.0")] +[assembly: AssemblyFileVersion("0.23.0.0")] diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile index d4a7b82c921..a5371dd82d0 100644 --- a/contrib/Vagrantfile +++ b/contrib/Vagrantfile @@ -46,7 +46,7 @@ sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options sudo apt-get install -qq ant openjdk-8-jdk maven # Python dependencies -sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-six python3-six +sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support # Ruby dependencies sudo apt-get install -qq ruby ruby-dev diff --git a/contrib/async-test/test-leaf.py b/contrib/async-test/test-leaf.py index 4ea4a9b8c04..c4772f706a9 100755 --- a/contrib/async-test/test-leaf.py +++ b/contrib/async-test/test-leaf.py @@ -1,4 +1,24 @@ #!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + import sys import time from thrift.transport import TTransport diff --git a/contrib/fb303/TClientInfo.cpp b/contrib/fb303/TClientInfo.cpp index a4b00cf2d58..c30b42b6122 100644 --- a/contrib/fb303/TClientInfo.cpp +++ b/contrib/fb303/TClientInfo.cpp @@ -149,7 +149,7 @@ void TClientInfoServerHandler::getStatsStrings(vector& result) { char addrBuf[INET6_ADDRSTRLEN]; const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf); if (addrStr == nullptr) { - // cerr << "no addr!" << endl; + // cerr << "no addr!" << '\n'; continue; } @@ -160,7 +160,7 @@ void TClientInfoServerHandler::getStatsStrings(vector& result) { char buf[256]; snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs, (uint64_t)info->getNCalls()); - + result.push_back(buf); } } diff --git a/contrib/fb303/cpp/ServiceTracker.cpp b/contrib/fb303/cpp/ServiceTracker.cpp index a2e670c768b..43e88474009 100644 --- a/contrib/fb303/cpp/ServiceTracker.cpp +++ b/contrib/fb303/cpp/ServiceTracker.cpp @@ -344,7 +344,7 @@ ServiceTracker::defaultLogMethod(int level, const string &message) break; } cout << '[' << level_string << "] [" << now_pretty << "] " - << message << endl; + << message << '\n'; } } diff --git a/contrib/fb303/py/Makefile.am b/contrib/fb303/py/Makefile.am index 060495e5819..706e10a35e2 100644 --- a/contrib/fb303/py/Makefile.am +++ b/contrib/fb303/py/Makefile.am @@ -18,6 +18,9 @@ # DESTDIR ?= / +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = setup.py src all: diff --git a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py index 5c8f409c1af..62a729e1d8f 100644 --- a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +++ b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py @@ -19,7 +19,6 @@ # under the License. # -from __future__ import print_function import sys import os from optparse import OptionParser diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml index 46f3cb18327..1a9b1f425eb 100644 --- a/contrib/thrift-maven-plugin/pom.xml +++ b/contrib/thrift-maven-plugin/pom.xml @@ -29,7 +29,7 @@ thrift-maven-plugin maven-plugin thrift-maven-plugin - 0.20.0 + 0.23.0 1.8 diff --git a/contrib/thrift.spec b/contrib/thrift.spec index 90bf4aae567..74b4ad89b57 100644 --- a/contrib/thrift.spec +++ b/contrib/thrift.spec @@ -28,7 +28,7 @@ Name: thrift License: Apache License v2.0 Group: Development Summary: RPC and serialization framework -Version: 0.20.0 +Version: 0.23.0 Release: 0 URL: http://thrift.apache.org Packager: Thrift Developers diff --git a/contrib/thrift_dump.cpp b/contrib/thrift_dump.cpp index 59c8ac863f5..01864d08383 100644 --- a/contrib/thrift_dump.cpp +++ b/contrib/thrift_dump.cpp @@ -80,12 +80,12 @@ int main(int argc, char *argv[]) { } } } catch (TProtocolException exn) { - cout << "Protocol Exception: " << exn.what() << endl; + cout << "Protocol Exception: " << exn.what() << '\n'; } catch (...) { oprot->getTransport()->flush(); } - cout << endl; + cout << '\n'; return 0; } diff --git a/contrib/transport-sample/ThriftCommon.cpp b/contrib/transport-sample/ThriftCommon.cpp index 2b676a88efb..9f087079e0a 100644 --- a/contrib/transport-sample/ThriftCommon.cpp +++ b/contrib/transport-sample/ThriftCommon.cpp @@ -7,7 +7,7 @@ namespace thriftcommon { //---------------------------------------------------------------------------- //Launch child process and pass R/W anonymous pipe handles on cmd line. - //This is a simple example and does not include elevation or other + //This is a simple example and does not include elevation or other //advanced features. // bool LaunchAnonPipeChild(std::string app, boost::shared_ptr transport) @@ -25,7 +25,7 @@ namespace thriftcommon //spawn the child process if (!CreateProcessA(nullptr, handles, nullptr,nullptr,TRUE,0,nullptr,nullptr,&si,&pi)) { - GlobalOutput.perror("TPipeServer CreateProcess failed, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer CreateProcess failed, GLE=", GetLastError()); return false; } diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs index 8d7ed390b49..631dc757e73 100644 --- a/contrib/zeromq/csharp/AssemblyInfo.cs +++ b/contrib/zeromq/csharp/AssemblyInfo.cs @@ -36,7 +36,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("0.20.0.0")] +[assembly: AssemblyVersion("0.23.0.0")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/contrib/zeromq/test-client.cpp b/contrib/zeromq/test-client.cpp index 159c25030d5..f2bd2133ed8 100644 --- a/contrib/zeromq/test-client.cpp +++ b/contrib/zeromq/test-client.cpp @@ -33,7 +33,7 @@ int main(int argc, char** argv) { usleep(50000); } else { int value = client.get(); - std::cout << value << std::endl; + std::cout << value << '\n'; } return 0; diff --git a/contrib/zeromq/test-server.py b/contrib/zeromq/test-server.py index d89b37ba207..299b84c523a 100755 --- a/contrib/zeromq/test-server.py +++ b/contrib/zeromq/test-server.py @@ -1,4 +1,24 @@ #!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + import zmq import TZmqServer import storage.ttypes diff --git a/debian/changelog b/debian/changelog index 147c4b4bf65..9b66cad8e1a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +thrift (0.22.0) stable; urgency=low + + * update to 0.22.0 + + -- Apache Thrift Developers Wed, 14 May 2025 22:08:00 +0100 + +thrift (0.21.0) stable; urgency=low + + * update to 0.21.0 + + -- Apache Thrift Developers Mon, 02 Sep 2024 23:30:00 +0100 + thrift (0.20.0) stable; urgency=low * update to 0.20.0 diff --git a/debian/control b/debian/control index 1b41991c3ec..06c0d483416 100644 --- a/debian/control +++ b/debian/control @@ -32,7 +32,7 @@ Description: Compiler for Thrift definition files Package: python-thrift Architecture: any Section: python -Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-six +Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: python-twisted-web, python-backports.ssl-match-hostname, python-ipaddress Provides: ${python:Provides} Description: Python bindings for Thrift (Python 2) @@ -65,7 +65,7 @@ Description: Python bindings for Thrift (debug version) Package: python3-thrift Architecture: any Section: python -Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}, python3-six +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: python3-twisted-web Provides: ${python:Provides} Description: Python bindings for Thrift (Python 3) diff --git a/debian/copyright b/debian/copyright index e39dc742c51..7245167c173 100644 --- a/debian/copyright +++ b/debian/copyright @@ -72,9 +72,12 @@ under the Apache 2.0 License: lib/netstd/Thrift/Transport/TTransport.cs lib/netstd/Thrift/Transport/TTransportException.cs lib/netstd/Thrift/Transport/TTransportFactory.cs - lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs - lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj - lib/rb/lib/thrift.rb + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj lib/st/README.md lib/st/thrift.st lib/cpp/test/OptionalRequiredTest.cpp diff --git a/doap.rdf b/doap.rdf index 703082acb81..88f445d7b9f 100644 --- a/doap.rdf +++ b/doap.rdf @@ -55,6 +55,16 @@ + + Apache Thrift + 2025-05-14 + 0.22.0 + + + Apache Thrift + 2024-09-02 + 0.21.0 + Apache Thrift 2024-02-04 diff --git a/doc/ReleaseManagement.md b/doc/ReleaseManagement.md index e06c9b4468e..d0eba5873ee 100644 --- a/doc/ReleaseManagement.md +++ b/doc/ReleaseManagement.md @@ -70,9 +70,9 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p 1. [Open Issues with a Fix Version](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20status%20in%20(OPEN%2C%20%27IN%20PROGRESS%27%2C%20REOPENED)%20and%20fixVersion%20is%20not%20empty) - these will be issues that someone placed a fixVersion on in Jira, but have not been resolved or closed yet. They are likely stale somehow. Resolutions for these issues include resolving or closing the issue in Jira, or simply removing the fixVersion if the issue hasn't been fixed. - 1. [Open Blocking Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(blocker)%20and%20status%20not%20in%20(closed)%20order%20by%20component%20ASC) - blocking issues should block a release. Scrub the list to see if they are really blocking the release, and if not change their priority. + 1. [Open Blocking Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(blocker)%20and%20status%20not%20in%20(closed,resolved)%20order%20by%20component%20ASC) - blocking issues should block a release. Scrub the list to see if they are really blocking the release, and if not change their priority. - 1. [Open Critical Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(critical)%20and%20status%20not%20in%20(closed)%20and%20type%20not%20in%20(%22wish%22)%20order%20by%20component%20ASC) - this list will end up in the known critical issues list in the changes file. Scrub it to make sure everything is actually critical. + 1. [Open Critical Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(critical)%20and%20status%20not%20in%20(closed,resolved)%20and%20type%20not%20in%20(%22wish%22)%20order%20by%20component%20ASC) - this list will end up in the known critical issues list in the changes file. Scrub it to make sure everything is actually critical. It is healthy to scrub these periodically, whether or not you are making a new release. @@ -126,12 +126,12 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p THRIFT-123 C++ - Library Drop C++03 [THRIFT-123](https://issues.apache.org/jira/browse/THRIFT-3978) - Drop C++03 ``` - For example, if the row above was row "B" in EXCEL it would look something like: + For example, if the row above was row "1" in EXCEL it would look something like: ```text - =CONCAT("[", B1, "]", + =CONCAT("[", A1, "]", "https://issues.apache.org/jira/browse/", - B1, " - ", B3) + A1, " - ", C1) ``` 1. Create a level 3 section in `CHANGES.md` under the release for each component and copy the items from the RelNote column into the changes file. @@ -145,15 +145,19 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p 1. On a linux system get a clean copy of the release branch, for example: ```bash - ~$ git clone -b "release/1.0.0" git@github.com:apache/thrift.git thrift-1.0.0-src + git clone -b "release/1.0.0" git@github.com:apache/thrift.git thrift-1.0.0-src ``` - 1. In the clean copy of the release branch, start a docker build container and run `make dist`: - - ```code - ~$ cd thrift-1.0.0-src - ~/thrift-1.0.0-src$ docker run -v $(pwd):/thrift/src:rw \ - -it thrift/thrift-build:ubuntu-bionic /bin/bash + 1. In the clean copy of the release branch, build the container image: + + ```bash + docker build -t thrift build/docker/ubuntu-jammy + ``` + + 1. Run the container and `make dist`: + + ```bash + docker run -v $(pwd):/thrift/src -it thrift /bin/bash root@8b4101188aa2:/thrift/src# ./bootstrap.sh && ./configure && make dist ``` @@ -275,9 +279,10 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p The CHANGES list for this release is available at: https://github.com/apache/thrift/blob/release/1.0.0/CHANGES.md - Please download, verify sig/sum, install and test the libraries and languages of your choice. + I start this voting thread with my own +1 vote. + This vote will close in 72 hours on 2019-07-06 21:00 UTC [ ] +1 Release this as Apache Thrift 1.0.0 @@ -340,7 +345,18 @@ Voting on the development mailing list provides additional benefits (wisdom from **NOTE:** If you get the error "gpg failed to sign the data" when tagging, try this fix: ```export GPG_TTY=$(tty)```. Alternatively, it may be necessary to specify the ```-u ``` as an additional argument. -1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags). Attach the statically built Windows thrift compiler as a binary here. +1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags). + + Attach the statically built Windows thrift compiler as a binary here. + + You may find it useful to use the button that automates release notes. + + We have *some* automation in place to get packages published to various package managers. To leverage this: + + - Please first create a "pre-release" and save. + - Then look at the Actions tab and look for the prereleased action. It will upload packages to package managers that we have automated and support "test" or "staging" modes. + - Go check out those packages and make sure they look correct. + - Come back to the release page and uncheck the "pre-release" checkbox and save. This will cause another action to get launched that publishes packages for real. 1. Merge the release branch into master. This ensures all changes made to fix up the release are in master. diff --git a/doc/install/README.md b/doc/install/README.md index d073e918dcf..0ebe77c7110 100644 --- a/doc/install/README.md +++ b/doc/install/README.md @@ -32,7 +32,7 @@ These are only required if you choose to build the libraries for the given langu * Gradle 8.4 * C#: Mono 1.2.4 (and pkg-config to detect it) or Visual Studio 2005+ * Python 2.6 (including header files for extension modules) -* PHP 5.0 (optionally including header files for extension modules) +* PHP 7.1 (optionally including header files for extension modules) * Ruby 1.8 * bundler gem * Erlang R12 (R11 works but not recommended) diff --git a/doc/specs/idl.md b/doc/specs/idl.md index 0980f5bbc6d..d2b59db8b7f 100644 --- a/doc/specs/idl.md +++ b/doc/specs/idl.md @@ -1,6 +1,6 @@ ## Thrift interface description language -For Thrift version 0.20.0. +For Thrift version 0.23.0. The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file. diff --git a/doc/specs/thrift-compact-protocol.md b/doc/specs/thrift-compact-protocol.md index a31a2d329c0..3e1c4b4548f 100644 --- a/doc/specs/thrift-compact-protocol.md +++ b/doc/specs/thrift-compact-protocol.md @@ -48,43 +48,38 @@ For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache ### Integer encoding -The _compact protocol_ uses multiple encodings for ints: the _zigzag int_, and the _var int_. +The _compact protocol_ uses [ZigZag](https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding)'ed +varint (aka [ULEB128](https://en.wikipedia.org/wiki/LEB128)) encoding. -Values of type `int32` and `int64` are first transformed to a *zigzag int*. A zigzag int folds positive and negative -numbers into the positive number space. When we read 0, 1, 2, 3, 4 or 5 from the wire, this is translated to 0, -1, 1, --2 or 2 respectively. Here are the (Scala) formulas to convert from int32/int64 to a zigzag int and back: +Values of type `int8` are encoded as one byte, rest are converted to `int64`, Zigzag'ed then encoded as varint. +Zigzag encoding maps signed integers to another domain, one where the sign bit is encoded in the least significant +bit (LSB). For example 0 maps to 0, -1 to 1, 1 to 2, -2 to 3, etc. Hence the term zigzag. Mapping the sign bit to +the LSB is important for compactness when the absolute value of the value is small, as ULEB encoding is more +efficient for small values. Here are the (Scala) formulas to convert from `int64` to a zigzag `int64` and back: ```scala -def intToZigZag(n: Int): Int = (n << 1) ^ (n >> 31) -def zigzagToInt(n: Int): Int = (n >>> 1) ^ - (n & 1) -def longToZigZag(n: Long): Long = (n << 1) ^ (n >> 63) -def zigzagToLong(n: Long): Long = (n >>> 1) ^ - (n & 1) +def ToZigzag(n: Long): Long = (n << 1) ^ (n >> 63) +def FromZigzag(n: Long): Long = (n >>> 1) ^ - (n & 1) ``` -The zigzag int is then encoded as a *var int*, also known as *Unsigned LEB128*. Var ints take 1 to 5 bytes (int32) or -1 to 10 bytes (int64). The process consists in taking a Big Endian unsigned integer, left-padding the bit-string to -make it a multiple of 7 bits, splitting it into 7-bit groups, prefixing the most-significant 7-bit group with the 0 -bit, prefixing the remaining 7-bit groups with the 1 bit and encoding the resulting bit-string in Little Endian. +A ULEB128 is encoded 7-bits at a time, starting from the LSB. Each 7-bits are encoded as 8-bits with the top bit set +if this is not the last byte, unset otherwise. For example, the integer 50399 is encoded as follows: ``` -50399 = 1100 0100 1101 1111 (Big Endian representation) - = 00000 1100 0100 1101 1111 (Left-padding) - = 0000011 0001001 1011111 (7-bit groups) - = 00000011 10001001 11011111 (Most-significant bit prefixes) - = 11011111 10001001 00000011 (Little Endian representation) - = 0xDF 0x89 0x03 +50399 = 11000100 11011111 (LSB) + = 0000011 0001001 1011111 (7-bit groups) + = 00000011 10001001 11011111 (add continuation bits) + = 0x03 0x89 0xDF (hex) +→ 0xDF 0x89 0x03 (write to ram LSB first) ``` -Var ints are sometimes used directly inside the compact protocol to represent positive numbers. - -To encode an `int16` as zigzag int, it is first converted to an `int32` and then encoded as such. The type `int8` simply -uses a single byte as in the binary protocol. +Varints are sometimes used directly inside the compact protocol to represent positive numbers. ### Enum encoding -The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an int32. +The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an `int32`. ### Binary encoding @@ -99,36 +94,33 @@ Binary protocol, binary data, 1+ bytes: Where: -* `byte length` is the length of the byte array, using var int encoding (must be >= 0). +* `byte length` is the length of the byte array, using varint encoding (must be >= 0). * `bytes` are the bytes of the byte array. ### String encoding -*String*s are first encoded to UTF-8, and then send as binary. They do not -include a NUL delimiter. +*String*s are first encoded to UTF-8, and then send as binary. They do not include a NUL delimiter. ### Double encoding -Values of type `double` are first converted to an int64 according to the IEEE 754 floating-point "double format" bit -layout. Most run-times provide a library to make this conversion. But while the binary protocol encodes the int64 -in 8 bytes in big endian order, the compact protocol encodes it in little endian order - this is due to an early -implementation bug that finally became the de-facto standard. +Values of type `double` are first converted to an `int64` according to the IEEE 754 floating-point "double format" +bit layout. Most run-times provide a library to make this conversion. But while the binary protocol encodes the +`int64` in 8 bytes in big endian order, the compact protocol encodes it in little endian order - this is due to an +early implementation bug that finally became the de-facto standard. ### Boolean encoding Booleans are encoded differently depending on whether it is a field value (in a struct) or an element value (in a set, -list or map). Field values are encoded directly in the field header. Element values of type `bool` are sent as an int8; -true as `1` and false as `0`. +list or map). Field values are encoded directly in the field header. Element values of type `bool` are sent as an +`int8`; true as `1` and false as `2`. ### Universal unique identifier encoding -Values of `uuid` type are expected as 16-byte binary in big endian (or "network") order. Byte order conversion -might be necessary on certain platforms, e.g. Windows holds GUIDs in a complex record-like structure whose -memory layout differs. +Values of `uuid` type are expected as 16-byte binary in big endian order. Byte order conversion might be necessary on +certain platforms, e.g. Windows holds GUIDs in a complex record-like structure whose memory layout differs. *Note*: Since the length is fixed, no `byte length` prefix is necessary and the field is always 16 bytes long. - ## Message A `Message` on the wire looks as follows: @@ -145,8 +137,8 @@ Where: * `pppppppp` is the protocol id, fixed to `1000 0010`, 0x82. * `mmm` is the message type, an unsigned 3 bit integer. * `vvvvv` is the version, an unsigned 5 bit integer, fixed to `00001`. -* `seq id` is the sequence id, a signed 32 bit integer encoded as a var int. -* `name length` is the byte length of the name field, a signed 32 bit integer encoded as a var int (must be >= 0). +* `seq id` is the sequence id, a signed 32 bit integer encoded as a varint. +* `name length` is the byte length of the name field, a signed 32 bit integer encoded as a varint (must be >= 0). * `name` is the method name to invoke, a UTF-8 encoded string. Message types are encoded with the following values: @@ -204,7 +196,7 @@ Where: * `dddd` is the field id delta, an unsigned 4 bits integer, strictly positive. * `tttt` is field-type id, an unsigned 4 bit integer. -* `field id` the field id, a signed 16 bit integer encoded as zigzag int. +* `field id` the field id, a varint (int16). Max field id is 32767. * `field-value` the encoded field value. The field id delta can be computed by `current-field-id - previous-field-id`, or just `current-field-id` if this is the @@ -250,14 +242,14 @@ Where: * `ssss` is the size, 4 bit unsigned int, values `0` - `14` * `tttt` is the element-type, a 4 bit unsigned int -* `size` is the size, a var int (int32), positive values `15` or higher +* `size` is the size, a varint (int32), positive values `15` or higher * `elements` are the encoded elements The short form should be used when the length is in the range 0 - 14 (inclusive). -The following element-types are used (see note below): +The following element-types are used (see note 1 below): -* `BOOL`, encoded as `2` +* `BOOL`, encoded as `1` or `2` (see note 2 below) * `I8`, encoded as `3` * `I16`, encoded as `4` * `I32`, encoded as `5` @@ -270,8 +262,12 @@ The following element-types are used (see note below): * `STRUCT`, used for structs and union fields, encoded as `12` * `UUID`, encoded as `13` -*Note*: Although field-types and element-types lists are currently very similar, there is _no guarantee_ that this will +*Note*: +1. Although field-types and element-types lists are currently very similar, there is _no guarantee_ that this will remain true after new types are added. +2. For historical and compatibility reasons, a reader should be capable to deal with *both* cases. +The only valid value in the original spec was `2`, but due to an widespread implementation bug the defacto +standard across large parts of the library became `1` instead. As a result, both values are now allowed. The maximum list/set size is configurable. By default there is no limit (meaning the limit is the maximum int32 value: 2147483647). diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..2f70a8824f0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,50 @@ +import globals from "globals"; +import js from "@eslint/js"; +import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; + +export default [ + { + ignores: [ + // TODO: Use eslint on js lib and generated code + + // Ignore lib/js for now, which uses jshint currently + "lib/js/*", + // Ignore all generated code for now + "**/gen-*/", + + // Don't lint nested node_modules + "**/node_modules/", + ], + }, + js.configs.recommended, + eslintPluginPrettierRecommended, + { + languageOptions: { + globals: { + ...globals.node, + }, + + ecmaVersion: 2022, + sourceType: "commonjs", + }, + + rules: { + "no-console": "off", + "no-var": "error", + "prefer-const": "error", + + "no-constant-condition": [ + "error", + { + checkLoops: false, + }, + ], + }, + }, + { + files: ["**/*.mjs"], + languageOptions: { + sourceType: "module", + }, + }, +]; diff --git a/go.mod b/go.mod index b435d78a368..8d1f8525a2c 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/apache/thrift -go 1.21 +go 1.24 diff --git a/lib/Makefile.am b/lib/Makefile.am index 3f717f1afc8..19177ccb537 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -102,6 +102,9 @@ endif # All of the libs that don't use Automake need to go in here # so they will end up in our release tarballs. +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ d \ dart \ diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am index b2061bbc789..80a51650a31 100644 --- a/lib/c_glib/Makefile.am +++ b/lib/c_glib/Makefile.am @@ -112,6 +112,9 @@ include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \ src/thrift/c_glib/processor/thrift_multiplexed_processor.h +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c index 9e80e107c2a..0df2fb0c326 100644 --- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c @@ -25,6 +25,14 @@ #include #include +/* object properties */ +enum _ThriftBinaryProtocolProperties +{ + PROP_0, + PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT, + PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT +}; + G_DEFINE_TYPE(ThriftBinaryProtocol, thrift_binary_protocol, THRIFT_TYPE_PROTOCOL) static guint64 @@ -561,6 +569,14 @@ thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol, return -1; } + ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); + if (bp->container_limit > 0 && sizei > bp->container_limit) { + g_set_error (error, THRIFT_PROTOCOL_ERROR, + THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, + "got size over limit (%d > %d)", sizei, bp->container_limit); + return -1; + } + if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), sizei * thrift_binary_protocol_get_min_serialized_size(protocol, k, error) + sizei * thrift_binary_protocol_get_min_serialized_size(protocol, v, error), @@ -618,6 +634,14 @@ thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol, return -1; } + ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); + if (bp->container_limit > 0 && sizei > bp->container_limit) { + g_set_error (error, THRIFT_PROTOCOL_ERROR, + THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, + "got size over limit (%d > %d)", sizei, bp->container_limit); + return -1; + } + if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), (sizei * thrift_binary_protocol_get_min_serialized_size(protocol, e, error)), error)) @@ -814,6 +838,23 @@ thrift_binary_protocol_read_string (ThriftProtocol *protocol, return -1; } + ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); + if (bp->string_limit > 0 && read_len > bp->string_limit) { + g_set_error (error, THRIFT_PROTOCOL_ERROR, + THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, + "got size over limit (%d > %d)", read_len, bp->string_limit); + *str = NULL; + return -1; + } + + ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); + ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); + if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), read_len, error)) + { + *str = NULL; + return -1; + } + /* allocate the memory for the string */ len = (guint32) read_len + 1; /* space for null terminator */ *str = g_new0 (gchar, len); @@ -854,8 +895,36 @@ thrift_binary_protocol_read_binary (ThriftProtocol *protocol, } xfer += ret; + if (read_len < 0) { + g_set_error (error, THRIFT_PROTOCOL_ERROR, + THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, + "got negative size of %d", read_len); + *buf = NULL; + *len = 0; + return -1; + } + + ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); + if (bp->string_limit > 0 && read_len > bp->string_limit) { + g_set_error (error, THRIFT_PROTOCOL_ERROR, + THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, + "got size over limit (%d > %d)", read_len, bp->string_limit); + *buf = NULL; + *len = 0; + return -1; + } + if (read_len > 0) { + ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); + ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); + if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), read_len, error)) + { + *buf = NULL; + *len = 0; + return -1; + } + /* allocate the memory as an array of unsigned char for binary data */ *len = (guint32) read_len; *buf = g_new (guchar, *len); @@ -885,9 +954,9 @@ thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftT switch (type) { case T_STOP: - return 0; + return 1; /* T_STOP needs to count itself */ case T_VOID: - return 0; + return 1; /* T_VOID needs to count itself */ case T_BOOL: return sizeof(gint8); case T_BYTE: @@ -903,7 +972,7 @@ thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftT case T_STRING: return sizeof(int); case T_STRUCT: - return 0; + return 1; /* empty struct needs at least 1 byte for the T_STOP */ case T_MAP: return sizeof(int); case T_SET: @@ -919,6 +988,48 @@ thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftT } } +/* property accessor */ +void +thrift_binary_protocol_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + ThriftBinaryProtocol *tb; + + THRIFT_UNUSED_VAR (pspec); + + tb = THRIFT_BINARY_PROTOCOL (object); + + switch (property_id) { + case PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT: + g_value_set_int (value, tb->string_limit); + break; + case PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT: + g_value_set_int (value, tb->container_limit); + break; + } +} + +/* property mutator */ +void +thrift_binary_protocol_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + ThriftBinaryProtocol *tb; + + THRIFT_UNUSED_VAR (pspec); + + tb = THRIFT_BINARY_PROTOCOL (object); + + switch (property_id) { + case PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT: + tb->string_limit = g_value_get_int (value); + break; + case PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT: + tb->container_limit = g_value_get_int (value); + break; + } +} + static void thrift_binary_protocol_init (ThriftBinaryProtocol *protocol) { @@ -929,7 +1040,39 @@ thrift_binary_protocol_init (ThriftBinaryProtocol *protocol) static void thrift_binary_protocol_class_init (ThriftBinaryProtocolClass *klass) { - ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); + ThriftProtocolClass *cls; + GObjectClass *gobject_class; + GParamSpec *param_spec; + + cls = THRIFT_PROTOCOL_CLASS (klass); + gobject_class = G_OBJECT_CLASS (klass); + param_spec = NULL; + + /* setup accessors and mutators */ + gobject_class->get_property = thrift_binary_protocol_get_property; + gobject_class->set_property = thrift_binary_protocol_set_property; + + param_spec = g_param_spec_int ("string_limit", + "Max allowed string size", + "Set the max string limit", + 0, /* min */ + G_MAXINT32, /* max */ + 0, /* default value */ + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT, + param_spec); + + param_spec = g_param_spec_int ("container_limit", + "Max allowed container size", + "Set the max container limit", + 0, /* min */ + G_MAXINT32, /* max */ + 0, /* default value */ + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT, + param_spec); cls->write_message_begin = thrift_binary_protocol_write_message_begin; cls->write_message_end = thrift_binary_protocol_write_message_end; diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h index bd8b84effbc..6d2bc3e55e2 100644 --- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h @@ -52,6 +52,10 @@ typedef struct _ThriftBinaryProtocol ThriftBinaryProtocol; struct _ThriftBinaryProtocol { ThriftProtocol parent; + + /* protected */ + gint32 string_limit; + gint32 container_limit; }; typedef struct _ThriftBinaryProtocolClass ThriftBinaryProtocolClass; diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c index 0aa9a6fe640..73be027c5dd 100644 --- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c @@ -1414,6 +1414,13 @@ thrift_compact_protocol_read_string (ThriftProtocol *protocol, return -1; } + ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); + ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); + if (read_len > 0 && !ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), read_len, error)) { + *str = NULL; + return -1; + } + /* allocate the memory as an array of unsigned char for binary data */ *str = g_new0 (gchar, read_len + 1); if (read_len > 0) { @@ -1468,6 +1475,14 @@ thrift_compact_protocol_read_binary (ThriftProtocol *protocol, } if (read_len > 0) { + ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); + ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); + if (!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), read_len, error)) { + *buf = NULL; + *len = 0; + return -1; + } + /* allocate the memory as an array of unsigned char for binary data */ *len = (guint32) read_len; *buf = g_new (guchar, *len); @@ -1505,9 +1520,9 @@ thrift_compact_protocol_get_min_serialized_size (ThriftProtocol *protocol, Thrif switch (type) { case T_STOP: - return 0; + return 1; /* T_STOP needs to count itself */ case T_VOID: - return 0; + return 1; /* T_VOID needs to count itself */ case T_BOOL: return sizeof(gint8); case T_DOUBLE: @@ -1523,7 +1538,7 @@ thrift_compact_protocol_get_min_serialized_size (ThriftProtocol *protocol, Thrif case T_STRING: return sizeof(gint8); case T_STRUCT: - return 0; + return 1; /* empty struct needs at least 1 byte for the T_STOP */ case T_MAP: return sizeof(gint8); case T_SET: diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c index 252f4bec96f..cb7199b9508 100644 --- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c @@ -471,10 +471,12 @@ thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type, GError **error) } case T_STRING: { - gpointer data; + gpointer data = NULL; guint32 len; gint32 ret = thrift_protocol_read_binary (protocol, &data, &len, error); - g_free (data); + if (data) { + g_free (data); + } return ret; } case T_STRUCT: diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c index d38d494b6a2..9ef0057ccaa 100644 --- a/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c +++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c @@ -91,6 +91,10 @@ thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf, give = t->buf->len; } + if (give == 0) { + return -1; + } + memcpy (buf, t->buf->data, give); g_byte_array_remove_range (t->buf, 0, give); diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c index 9d3f25e75e7..a03eb9e2b7a 100644 --- a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c +++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c @@ -164,7 +164,7 @@ thrift_transport_checkReadBytesAvailable(ThriftTransport *transport, glong numBy { gboolean boolean = TRUE; ThriftTransport *tt = THRIFT_TRANSPORT (transport); - if(tt->remainingMessageSize_ < numBytes) + if(tt->remainingMessageSize_ < numBytes || numBytes < 0) { g_set_error(error, THRIFT_TRANSPORT_ERROR, diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt index 4d3092fb8a1..4f60473b25c 100644 --- a/lib/c_glib/test/CMakeLists.txt +++ b/lib/c_glib/test/CMakeLists.txt @@ -231,7 +231,7 @@ add_custom_command(OUTPUT gen-cpp/ThriftTest.h gen-cpp/ThriftTest_constants.h gen-cpp/ThriftTest_types.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift ) # TODO: Add memory checks using ctest_memcheck or similar diff --git a/lib/c_glib/test/Makefile.am b/lib/c_glib/test/Makefile.am index f3a0c30df67..e61f875da8f 100644 --- a/lib/c_glib/test/Makefile.am +++ b/lib/c_glib/test/Makefile.am @@ -18,7 +18,7 @@ # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc -SUBDIRS = +SUBDIRS = fuzz BUILT_SOURCES = \ gen-c_glib/t_test_container_test_types.c \ @@ -34,7 +34,8 @@ BUILT_SOURCES = \ gen-c_glib/t_test_container_service.h \ gen-c_glib/t_test_srv.h \ gen-c_glib/t_test_thrift_test.h \ - gen-c_glib/t_test_thrift_test_types.h + gen-c_glib/t_test_thrift_test_types.h \ + gen-c_glib/t_test_enum_test_types.h AM_CPPFLAGS = -I../src -I./gen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) \ @@ -335,7 +336,7 @@ gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/t_test_optional_requ gen-c_glib/t_test_second_service.c gen-c_glib/t_test_thrift_test.c gen-c_glib/t_test_thrift_test_types.c gen-c_glib/t_test_second_service.h gen-c_glib/t_test_thrift_test.h gen-c_glib/t_test_thrift_test_types.h: ../../../test/v0.16/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< -gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest_types.cpp: ../../../test/v0.16/ThriftTest.thrift $(THRIFT) +gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest_types.cpp: ../../../test/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen cpp $< TESTS = \ @@ -401,6 +402,9 @@ CLEANFILES = \ *.gcda \ *.gcov +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ ContainerTest.thrift diff --git a/lib/c_glib/test/fuzz/Makefile.am b/lib/c_glib/test/fuzz/Makefile.am new file mode 100644 index 00000000000..e7d0e355521 --- /dev/null +++ b/lib/c_glib/test/fuzz/Makefile.am @@ -0,0 +1,66 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc + +BUILT_SOURCES = \ + gen-c_glib/fuzz_test_no_uuid_types.h \ + gen-c_glib/fuzz_test_no_uuid_types.c + +noinst_LTLIBRARIES = libtestgencfuzz.la +nodist_libtestgencfuzz_la_SOURCES = \ + gen-c_glib/fuzz_test_no_uuid_types.c \ + gen-c_glib/fuzz_test_no_uuid_types.h + +libtestgencfuzz_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la + +AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) +AM_CFLAGS = -g $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) +AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) + +if USING_CLANG +AM_LDFLAGS += -fsanitize=fuzzer +endif + +check_PROGRAMS = fuzz_parse_compact fuzz_parse_binary + +fuzz_parse_compact_SOURCES = fuzz_parse_compact.c +fuzz_parse_compact_LDADD = \ + libtestgencfuzz.la \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o + +fuzz_parse_binary_SOURCES = fuzz_parse_binary.c +fuzz_parse_binary_LDADD = \ + libtestgencfuzz.la \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ + $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o + +# +# Common thrift code generation rules +# +gen-c_glib/fuzz_test_no_uuid_types.c gen-c_glib/fuzz_test_no_uuid_types.h: $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift + $(THRIFT) --gen c_glib -r $< + +clean-local: + $(RM) -r gen-c_glib/ + $(RM) *.o + $(RM) libtestgencfuzz.la \ No newline at end of file diff --git a/lib/c_glib/test/fuzz/README.md b/lib/c_glib/test/fuzz/README.md new file mode 100644 index 00000000000..d1a100e8b12 --- /dev/null +++ b/lib/c_glib/test/fuzz/README.md @@ -0,0 +1,20 @@ +# C GLib Fuzzing README + +To build the fuzz targets, run `make check` in this directory. The build system uses LLVM's libFuzzer for fuzzing the C GLib Thrift implementation. + +These are standard libFuzzer targets, so you can run them using the standard libFuzzer interface. After building, you can run a fuzzer using: +```bash +./ +``` + +We currently have two fuzz targets: + +* fuzz_parse_binary -- fuzzes the deserialization of the Binary protocol +* fuzz_parse_compact -- fuzzes the deserialization of the Compact protocol +* TODO: Add round trip fuzzers, similar to other languages. + +The fuzzers use libFuzzer's built-in mutation engine to generate test cases. Each fuzzer implements the standard `LLVMFuzzerTestOneInput` interface. + +For more information about libFuzzer and its options, see the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html). + +You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these C GLib fuzzers, since the wire formats are identical between implementations. diff --git a/lib/c_glib/test/fuzz/fuzz_parse_binary.c b/lib/c_glib/test/fuzz/fuzz_parse_binary.c new file mode 100644 index 00000000000..25b9fe0f0fc --- /dev/null +++ b/lib/c_glib/test/fuzz/fuzz_parse_binary.c @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "gen-c_glib/fuzz_test_no_uuid_types.h" +#include + +// 10MB message size limit to prevent over-allocation during fuzzing +#define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024) + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + GError* error = NULL; + + // Create a GByteArray with the fuzz data + GByteArray* byte_array = g_byte_array_new(); + g_byte_array_append(byte_array, data, size); + + // Create a ThriftConfiguration with message size limits + ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, + "max_message_size", FUZZ_MAX_MESSAGE_SIZE, + "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, + NULL); + + // Create a memory buffer transport with the byte array and configuration + ThriftTransport* transport = THRIFT_TRANSPORT( + g_object_new(THRIFT_TYPE_MEMORY_BUFFER, + "buf", byte_array, + "buf_size", size, + "configuration", tconfiguration, + NULL)); + + // Create a binary protocol + ThriftProtocol* protocol = THRIFT_PROTOCOL( + g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, + "transport", transport, + NULL)); + + // Create a FuzzTest struct to read into + FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL); + FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct); + + // Try to read the struct from the fuzz data + THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error); + + // Clean up + g_object_unref(test_struct); + g_object_unref(protocol); + g_object_unref(transport); + g_object_unref(tconfiguration); + if (error) { + g_error_free(error); + } + + return 0; +} \ No newline at end of file diff --git a/lib/c_glib/test/fuzz/fuzz_parse_compact.c b/lib/c_glib/test/fuzz/fuzz_parse_compact.c new file mode 100644 index 00000000000..5e0e2c17c5a --- /dev/null +++ b/lib/c_glib/test/fuzz/fuzz_parse_compact.c @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "gen-c_glib/fuzz_test_no_uuid_types.h" +#include + +// 10MB message size limit to prevent over-allocation during fuzzing +#define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024) + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + GError* error = NULL; + + // Create a GByteArray with the fuzz data + GByteArray* byte_array = g_byte_array_new(); + g_byte_array_append(byte_array, data, size); + + // Create a ThriftConfiguration with message size limits + ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, + "max_message_size", FUZZ_MAX_MESSAGE_SIZE, + "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, + NULL); + + // Create a memory buffer transport with the byte array and configuration + ThriftTransport* transport = THRIFT_TRANSPORT( + g_object_new(THRIFT_TYPE_MEMORY_BUFFER, + "buf", byte_array, + "buf_size", size, + "configuration", tconfiguration, + NULL)); + + // Create a compact protocol + ThriftProtocol* protocol = THRIFT_PROTOCOL( + g_object_new(THRIFT_TYPE_COMPACT_PROTOCOL, + "transport", transport, + NULL)); + + // // Create a FuzzTest struct to read into + FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL); + FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct); + + // Try to read the struct from the fuzz data + THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error); + + // Clean up + g_object_unref(test_struct); + g_object_unref(protocol); + g_object_unref(transport); + g_object_unref(tconfiguration); + if (error) { + g_error_free(error); + } + + return 0; +} \ No newline at end of file diff --git a/lib/c_glib/test/testthrifttestclient.cpp b/lib/c_glib/test/testthrifttestclient.cpp index 77daf3d37fa..745feb786c0 100644 --- a/lib/c_glib/test/testthrifttestclient.cpp +++ b/lib/c_glib/test/testthrifttestclient.cpp @@ -51,7 +51,6 @@ using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; -using std::endl; using std::fixed; using std::make_pair; using std::map; @@ -76,51 +75,56 @@ class TestHandler : public ThriftTestIf { TestHandler() = default; void testVoid() override { - cout << "[C -> C++] testVoid()" << endl; + cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { - cout << "[C -> C++] testString(\"" << thing << "\")" << endl; + cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { - cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl; + cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { - cout << "[C -> C++] testByte(" << (int)thing << ")" << endl; + cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { - cout << "[C -> C++] testI32(" << thing << ")" << endl; + cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { - cout << "[C -> C++] testI64(" << thing << ")" << endl; + cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); - cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl; + cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { - cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl; + cout << "[C -> C++] testBinary(\"" << thing << "\")" << '\n'; + out = thing; + } + + void testUuid(apache::thrift::TUuid& out, const apache::thrift::TUuid& thing) override { + cout << "[C -> C++] testUuid(\"" << thing << "\")" << '\n'; out = thing; } void testStruct(Xtruct& out, const Xtruct &thing) override { - cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << endl; + cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << '\n'; out = thing; } void testNest(Xtruct2& out, const Xtruct2& nest) override { const Xtruct &thing = nest.struct_thing; - cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << endl; + cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << '\n'; out = nest; } @@ -136,7 +140,7 @@ class TestHandler : public ThriftTestIf { } cout << m_iter->first << " => " << m_iter->second; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -152,7 +156,7 @@ class TestHandler : public ThriftTestIf { } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -169,7 +173,7 @@ class TestHandler : public ThriftTestIf { } cout << *s_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -185,21 +189,21 @@ class TestHandler : public ThriftTestIf { } cout << *l_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { - cout << "[C -> C++] testEnum(" << thing << ")" << endl; + cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { - cout << "[C -> C++] testTypedef(" << thing << ")" << endl; + cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; return thing; } void testMapMap(map > &mapmap, const int32_t hello) override { - cout << "[C -> C++] testMapMap(" << hello << ")" << endl; + cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; @@ -216,7 +220,7 @@ class TestHandler : public ThriftTestIf { void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); - cout << "[C -> C++] testInsanity()" << endl; + cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; @@ -278,7 +282,7 @@ class TestHandler : public ThriftTestIf { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; } @@ -288,7 +292,7 @@ class TestHandler : public ThriftTestIf { THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); - cout << "[C -> C++] testMulti()" << endl; + cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; @@ -299,7 +303,7 @@ class TestHandler : public ThriftTestIf { void testException(const std::string &arg) noexcept(false) override { - cout << "[C -> C++] testException(" << arg << ")" << endl; + cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; @@ -317,7 +321,7 @@ class TestHandler : public ThriftTestIf { void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { - cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl; + cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; @@ -336,9 +340,9 @@ class TestHandler : public ThriftTestIf { } void testOneway(int sleepFor) override { - cout << "testOneway(" << sleepFor << "): Sleeping..." << endl; + cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); - cout << "testOneway(" << sleepFor << "): done sleeping!" << endl; + cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; diff --git a/lib/c_glib/test/testthrifttestzlibclient.cpp b/lib/c_glib/test/testthrifttestzlibclient.cpp index 5c4b931570d..783d06550a2 100644 --- a/lib/c_glib/test/testthrifttestzlibclient.cpp +++ b/lib/c_glib/test/testthrifttestzlibclient.cpp @@ -46,7 +46,6 @@ using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; -using std::endl; using std::fixed; using std::make_pair; using std::map; @@ -71,51 +70,56 @@ class TestHandler : public ThriftTestIf { TestHandler() = default; void testVoid() override { - cout << "[C -> C++] testVoid()" << endl; + cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { - cout << "[C -> C++] testString(\"" << thing << "\")" << endl; + cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { - cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl; + cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { - cout << "[C -> C++] testByte(" << (int)thing << ")" << endl; + cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { - cout << "[C -> C++] testI32(" << thing << ")" << endl; + cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { - cout << "[C -> C++] testI64(" << thing << ")" << endl; + cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); - cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl; + cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { - cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl; + cout << "[C -> C++] testBinary(\"" << thing << "\")" << '\n'; + out = thing; + } + + void testUuid(apache::thrift::TUuid& out, const apache::thrift::TUuid& thing) override { + cout << "[C -> C++] testUuid(\"" << thing << "\")" << '\n'; out = thing; } void testStruct(Xtruct& out, const Xtruct &thing) override { - cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << endl; + cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << '\n'; out = thing; } void testNest(Xtruct2& out, const Xtruct2& nest) override { const Xtruct &thing = nest.struct_thing; - cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << endl; + cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << '\n'; out = nest; } @@ -131,7 +135,7 @@ class TestHandler : public ThriftTestIf { } cout << m_iter->first << " => " << m_iter->second; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -147,7 +151,7 @@ class TestHandler : public ThriftTestIf { } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -164,7 +168,7 @@ class TestHandler : public ThriftTestIf { } cout << *s_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -180,21 +184,22 @@ class TestHandler : public ThriftTestIf { } cout << *l_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { - cout << "[C -> C++] testEnum(" << thing << ")" << endl; + cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { - cout << "[C -> C++] testTypedef(" << thing << ")" << endl; - return thing; } + cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; + return thing; + } void testMapMap(map > &mapmap, const int32_t hello) override { - cout << "[C -> C++] testMapMap(" << hello << ")" << endl; + cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; @@ -211,7 +216,7 @@ class TestHandler : public ThriftTestIf { void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); - cout << "[C -> C++] testInsanity()" << endl; + cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; @@ -273,7 +278,7 @@ class TestHandler : public ThriftTestIf { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; } @@ -283,7 +288,7 @@ class TestHandler : public ThriftTestIf { THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); - cout << "[C -> C++] testMulti()" << endl; + cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; @@ -292,9 +297,9 @@ class TestHandler : public ThriftTestIf { } void testException(const std::string &arg) - throw(Xception, apache::thrift::TException) override + noexcept(false) override { - cout << "[C -> C++] testException(" << arg << ")" << endl; + cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; @@ -310,9 +315,9 @@ class TestHandler : public ThriftTestIf { } } - void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) override { + void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { - cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl; + cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; @@ -331,9 +336,9 @@ class TestHandler : public ThriftTestIf { } void testOneway(int sleepFor) override { - cout << "testOneway(" << sleepFor << "): Sleeping..." << endl; + cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); - cout << "testOneway(" << sleepFor << "): done sleeping!" << endl; + cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; diff --git a/lib/cl/Makefile.am b/lib/cl/Makefile.am index 34b38861d23..a54eb922eb4 100644 --- a/lib/cl/Makefile.am +++ b/lib/cl/Makefile.am @@ -32,6 +32,9 @@ clean-local: $(RM) run-tests quicklisp.lisp backport-update.zip $(RM) -rf lib externals quicklisp +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ README.md \ READMES \ diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt index 6a66e5ad1a7..5980734f380 100644 --- a/lib/cpp/CMakeLists.txt +++ b/lib/cpp/CMakeLists.txt @@ -31,6 +31,7 @@ endif() set(thriftcpp_SOURCES src/thrift/TApplicationException.cpp src/thrift/TOutput.cpp + src/thrift/TUuid.cpp src/thrift/async/TAsyncChannel.cpp src/thrift/async/TAsyncProtocolProcessor.cpp src/thrift/async/TConcurrentClientSyncInfo.h diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am index c015b0db60f..3d7beab68ae 100644 --- a/lib/cpp/Makefile.am +++ b/lib/cpp/Makefile.am @@ -57,6 +57,7 @@ AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FOR libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \ src/thrift/TOutput.cpp \ + src/thrift/TUuid.cpp \ src/thrift/VirtualProfiling.cpp \ src/thrift/async/TAsyncChannel.cpp \ src/thrift/async/TAsyncProtocolProcessor.cpp \ @@ -136,6 +137,7 @@ include_thrift_HEADERS = \ src/thrift/thrift-config.h \ src/thrift/thrift_export.h \ src/thrift/TDispatchProcessor.h \ + src/thrift/TUuid.h \ src/thrift/Thrift.h \ src/thrift/TOutput.h \ src/thrift/TProcessor.h \ @@ -252,6 +254,9 @@ WINDOWS_DIST = \ libthriftnb.vcxproj.filters \ 3rdparty.props +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ diff --git a/lib/cpp/README.md b/lib/cpp/README.md index 8074484f197..74983aeb1ff 100644 --- a/lib/cpp/README.md +++ b/lib/cpp/README.md @@ -232,6 +232,32 @@ OpenSSL's RAND_poll() when OpenSSL library is first initialized. The PRNG seed is key to the application security. This method should be overridden if it's not strong enough for you. +# Thrift UUID + +The `uuid` `BaseType` is implemented in C++ by the `apache::thrift::TUuid` class. This class +is a strong wrapper class around an internal buffer of 16 bytes. + +The `apache::thrift::TUuid` supports construction from different UUID string representations. +Some examples of supported string formats are: + +* `"hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh"` +* `"{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}"` +* `"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"` +* `"{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}"` + +## `TUuid` and `boost::uuids::uuid` + +Internally the TUuid class is implemented using the `boost::uuids::uuid` library. As a result the TUuid +can seamlessly interoperate with the boost UUID type since the underlying data structure is the same. + +For convenience, when boost is already used by a project the `THRIFT_TUUID_SUPPORT_BOOST_UUID` preprocessor +directive can be set when including the thrift library to enable construction of a `TUuid` from a +`boost::uuids::uuid`. By default this is an implicit constructor that can be changed to be explicit +by defining the `THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT` preprocessor directive. + +The thrift library does not need to be compiled differently when this constructor is needed. The preprocessor +directives can be set on the project that uses the thrift library. + # Deprecations ## 0.12.0 diff --git a/lib/cpp/libthrift.vcxproj b/lib/cpp/libthrift.vcxproj index 0b5e16de7c4..7fcccfe99ee 100644 --- a/lib/cpp/libthrift.vcxproj +++ b/lib/cpp/libthrift.vcxproj @@ -57,6 +57,7 @@ + @@ -96,6 +97,7 @@ + diff --git a/lib/cpp/libthrift.vcxproj.filters b/lib/cpp/libthrift.vcxproj.filters index 98426fac85b..4b2ba3b2782 100644 --- a/lib/cpp/libthrift.vcxproj.filters +++ b/lib/cpp/libthrift.vcxproj.filters @@ -4,6 +4,7 @@ transport + @@ -106,6 +107,7 @@ protocol + diff --git a/lib/cpp/src/thrift/TDispatchProcessor.h b/lib/cpp/src/thrift/TDispatchProcessor.h index ae522b2d846..8654dc674cb 100644 --- a/lib/cpp/src/thrift/TDispatchProcessor.h +++ b/lib/cpp/src/thrift/TDispatchProcessor.h @@ -61,7 +61,7 @@ class TDispatchProcessorT : public TProcessor { // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } @@ -76,7 +76,7 @@ class TDispatchProcessorT : public TProcessor { in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } @@ -114,7 +114,7 @@ class TDispatchProcessor : public TProcessor { in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } diff --git a/lib/cpp/src/thrift/TNonCopyable.h b/lib/cpp/src/thrift/TNonCopyable.h index a60f1f0fb4b..51c94e2a0d5 100644 --- a/lib/cpp/src/thrift/TNonCopyable.h +++ b/lib/cpp/src/thrift/TNonCopyable.h @@ -30,7 +30,7 @@ namespace thrift { class TNonCopyable { protected: TNonCopyable() = default; - ~TNonCopyable() = default; + virtual ~TNonCopyable() = default; TNonCopyable(const TNonCopyable&) = delete; TNonCopyable& operator=(const TNonCopyable&) = delete; diff --git a/lib/cpp/src/thrift/TOutput.cpp b/lib/cpp/src/thrift/TOutput.cpp index 971e5dbf7b1..495db6cd1b8 100644 --- a/lib/cpp/src/thrift/TOutput.cpp +++ b/lib/cpp/src/thrift/TOutput.cpp @@ -31,8 +31,6 @@ namespace apache { namespace thrift { -THRIFT_EXPORT TOutput GlobalOutput; - TOutput::TOutput() : f_(&errorTimeWrapper) {} void TOutput::printf(const char* message, ...) { @@ -85,6 +83,8 @@ void TOutput::printf(const char* message, ...) { f_(heap_buf); } free(heap_buf); +#else + THRIFT_UNUSED_VARIABLE(message); #endif } @@ -96,6 +96,8 @@ void TOutput::errorTimeWrapper(const char* msg) { THRIFT_CTIME_R(&now, dbgtime); dbgtime[24] = 0; fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg); +#else + THRIFT_UNUSED_VARIABLE(msg); #endif } @@ -144,5 +146,11 @@ std::string TOutput::strerror_s(int errno_copy) { return std::string(b_error); #endif // __ZEPHYR__ } + +TOutput& TOutput::instance() { + static TOutput instance; + return instance; +} + } } // apache::thrift diff --git a/lib/cpp/src/thrift/TOutput.h b/lib/cpp/src/thrift/TOutput.h index 26c9a563aed..bd006306070 100644 --- a/lib/cpp/src/thrift/TOutput.h +++ b/lib/cpp/src/thrift/TOutput.h @@ -20,8 +20,6 @@ #ifndef _THRIFT_OUTPUT_H_ #define _THRIFT_OUTPUT_H_ 1 -#include - namespace apache { namespace thrift { @@ -49,11 +47,13 @@ class TOutput { /** Just like strerror_r but returns a C++ string object. */ static std::string strerror_s(int errno_copy); + /** Get a singleton instance of the global TOutput object used by + * the library internally. */ + static TOutput& instance(); + private: void (*f_)(const char*); }; - -THRIFT_EXPORT extern TOutput GlobalOutput; } } // namespace apache::thrift diff --git a/lib/cpp/src/thrift/TToString.h b/lib/cpp/src/thrift/TToString.h index d91c58c4b2e..fe460326918 100644 --- a/lib/cpp/src/thrift/TToString.h +++ b/lib/cpp/src/thrift/TToString.h @@ -45,6 +45,14 @@ std::string to_string(const T& t) { return o.str(); } +// special handling of i8 datatypes (THRIFT-5272) +inline std::string to_string(const int8_t& t) { + std::ostringstream o; + o.imbue(default_locale); + o << static_cast(t); + return o.str(); +} + // TODO: replace the computations below with std::numeric_limits::max_digits10 once C++11 // is enabled. inline std::string to_string(const float& t) { diff --git a/lib/cpp/src/thrift/TUuid.cpp b/lib/cpp/src/thrift/TUuid.cpp new file mode 100644 index 00000000000..062b286d8b5 --- /dev/null +++ b/lib/cpp/src/thrift/TUuid.cpp @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include +#include +#include + +namespace apache { +namespace thrift { + +namespace { +static const boost::uuids::string_generator gen; +} + +TUuid::TUuid(const std::string& str) noexcept { + std::fill(this->begin(), this->end(), 0); + if (str.empty()) { + return ; + } + + try { + const boost::uuids::uuid uuid = gen(str); + std::copy(uuid.begin(), uuid.end(), this->begin()); + } catch (const std::runtime_error&) { + // Invalid string most probably + } +} + +bool TUuid::is_nil() const noexcept { + boost::uuids::uuid uuid_tmp{}; + std::copy(this->begin(), this->end(), std::begin(uuid_tmp)); + return uuid_tmp.is_nil(); +} + +std::string to_string(const TUuid& in) { + boost::uuids::uuid uuid_tmp{}; + std::copy(std::begin(in), std::end(in), std::begin(uuid_tmp)); + return boost::uuids::to_string(uuid_tmp); +} + + +} +} // apache::thrift \ No newline at end of file diff --git a/lib/cpp/src/thrift/TUuid.h b/lib/cpp/src/thrift/TUuid.h new file mode 100644 index 00000000000..405772aedc5 --- /dev/null +++ b/lib/cpp/src/thrift/TUuid.h @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _THRIFT_TUUID_H_ +#define _THRIFT_TUUID_H_ 1 + +#include + +#ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID +#include +#endif // THRIFT_TUUID_SUPPORT_BOOST_UUID + +#include +#include + +namespace apache { +namespace thrift { + +/** + * Thrift wrapper class for a UUID type. + * + * The UUID is stored as a 16 byte buffer. + * This class stores the UUID in network order when assigned from a string. + */ +class TUuid { +public: + typedef uint8_t value_type; + typedef uint8_t* iterator; + typedef uint8_t const* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + TUuid() = default; + TUuid(const TUuid& other) = default; + TUuid(TUuid&& other) = default; + TUuid& operator=(const TUuid&) = default; + TUuid& operator=(TUuid&&) = default; + ~TUuid() = default; + + /** + * Construct the object from a 16 byte buffer. + */ + explicit TUuid(const uint8_t (&data)[16]) noexcept + { + std::copy(std::begin(data), std::end(data), std::begin(this->data_)); + } + + /** + * Construct the object from the specified string. + * + * Supported string formats are: + * - "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh" + * - "{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}" + * - "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" + * - "{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}" + * + * If the string is invalid, the object will be set to a + * nil (empty) UUID. + */ + explicit TUuid(const std::string& str) noexcept; + +#ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + /** + * Construct the TUuid from a boost::uuids::uuid. + * + * This constructor will only be available if the THRIFT_TUUID_SUPPORT_BOOST_UUID + * compiler directive is set when this file is included. + * + * This constructor is by default implicit. It can be made explicit by defining the + * THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT compiler directive. + */ + #ifdef THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + explicit + #endif // THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + TUuid(const boost::uuids::uuid& buuid) noexcept + { + std::copy(buuid.begin(), buuid.end(), std::begin(this->data_)); + } +#endif // THRIFT_TUUID_SUPPORT_BOOST_UUID + + /** + * Check if the UUID is nil. + */ + bool is_nil() const noexcept; + + /** + * Compare two TUuid objects for equality. + */ + inline bool operator==(const TUuid& other) const; + + /** + * Compare two TUuid objects for inequality. + */ + inline bool operator!=(const TUuid& other) const; + + iterator begin() noexcept { return data_; } + const_iterator begin() const noexcept { return data_; } + iterator end() noexcept { return data_ + size(); } + const_iterator end() const noexcept { return data_ + size(); } + size_type size() const noexcept { return 16; } + inline const_iterator data() const { return data_; } + inline iterator data() { return data_; } + + void swap(TUuid& other) noexcept { std::swap(data_, other.data_); } + +private: + /** + * The UUID data. + */ + uint8_t data_[16] = {}; +}; + +/** + * Get the String representation of a TUUID. + * + * The format returned is: + * - "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh" + */ +std::string to_string(const TUuid& uuid) noexcept(false); + +/** + * Swap two TUuid objects + */ +inline void swap(TUuid& lhs, TUuid& rhs) noexcept { + lhs.swap(rhs); +} + +/** + * TUuid equality comparison operator implementation + */ +inline bool TUuid::operator==(const TUuid& other) const { + // Compare using temporary strings. + // Can't use strcmp() since we expect embeded zeros + // Perhaps the reason we should use std::array instead + return std::string(this->begin(), this->end()) == std::string(other.begin(), other.end()); +} + +/** + * TUuid inequality comparison operator implementation + */ +inline bool TUuid::operator!=(const TUuid& other) const { + return !(*this == other); +} + +/** + * TUuid ostream stream operator implementation + */ +inline std::ostream& operator<<(std::ostream& out, const TUuid& obj) { + out << to_string(obj); + return out; +} + +} // namespace thrift +} // namespace apache + +#endif // #ifndef _THRIFT_TUUID_H_ diff --git a/lib/cpp/src/thrift/Thrift.h b/lib/cpp/src/thrift/Thrift.h index d5066ee7107..8c330f98ad5 100644 --- a/lib/cpp/src/thrift/Thrift.h +++ b/lib/cpp/src/thrift/Thrift.h @@ -50,20 +50,27 @@ namespace apache { namespace thrift { -class TEnumIterator - : public std::iterator > { +class TEnumIterator { public: + using iterator_category = std::forward_iterator_tag; + using value_type = std::pair; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + TEnumIterator(int n, int* enums, const char** names) : ii_(0), n_(n), enums_(enums), names_(names) {} int operator++() { return ++ii_; } - bool operator!=(const TEnumIterator& end) { - THRIFT_UNUSED_VARIABLE(end); - assert(end.n_ == -1); - return (ii_ != n_); + bool operator==(const TEnumIterator& rhs) const { + bool is_end = ii_ == n_ || n_ == -1; + bool is_rhs_end = rhs.ii_ == rhs.n_ || rhs.n_ == -1; + return (ii_ == rhs.ii_ && n_ == rhs.n_) || (is_end && is_rhs_end); } + bool operator!=(const TEnumIterator& rhs) const { return !(*this == rhs); } + std::pair operator*() const { return std::make_pair(enums_[ii_], names_[ii_]); } private: diff --git a/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h b/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h index 2a694ac53bb..3ada6355ba5 100644 --- a/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h +++ b/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h @@ -62,7 +62,7 @@ class TAsyncDispatchProcessorT : public TAsyncProcessor { // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } @@ -79,7 +79,7 @@ class TAsyncDispatchProcessorT : public TAsyncProcessor { in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } @@ -123,7 +123,7 @@ class TAsyncDispatchProcessor : public TAsyncProcessor { // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { - GlobalOutput.printf("received invalid message type %d from client", mtype); + TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } diff --git a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h index 0bc5eb565f5..dd9b055e87e 100644 --- a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h +++ b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h @@ -36,7 +36,7 @@ class TConcurrentClientSyncInfo; class TConcurrentSendSentry { public: explicit TConcurrentSendSentry(TConcurrentClientSyncInfo* sync); - ~TConcurrentSendSentry(); + virtual ~TConcurrentSendSentry(); void commit(); @@ -48,7 +48,7 @@ class TConcurrentSendSentry { class TConcurrentRecvSentry { public: TConcurrentRecvSentry(TConcurrentClientSyncInfo* sync, int32_t seqid); - ~TConcurrentRecvSentry(); + virtual ~TConcurrentRecvSentry(); void commit(); diff --git a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp index 7656596859a..43d4034f618 100644 --- a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp +++ b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp @@ -147,8 +147,7 @@ void TEvhttpClientChannel::finish(struct evhttp_request* req) { self->finish(req); } catch (std::exception& e) { // don't propagate a C++ exception in C code (e.g. libevent) - std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what() - << std::endl; + std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what() << '\n'; } } } diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.cpp b/lib/cpp/src/thrift/async/TEvhttpServer.cpp index 7d2cf21c0fc..bea9001500d 100644 --- a/lib/cpp/src/thrift/async/TEvhttpServer.cpp +++ b/lib/cpp/src/thrift/async/TEvhttpServer.cpp @@ -127,13 +127,13 @@ void TEvhttpServer::complete(RequestContext* ctx, bool success) { int rv = evhttp_add_header(ctx->req->output_headers, "Content-Type", "application/x-thrift"); if (rv != 0) { // TODO: Log an error. - std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << '\n'; } struct evbuffer* buf = evbuffer_new(); if (buf == nullptr) { // TODO: Log an error. - std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << '\n'; } else { uint8_t* obuf; uint32_t sz; @@ -141,8 +141,7 @@ void TEvhttpServer::complete(RequestContext* ctx, bool success) { int ret = evbuffer_add(buf, obuf, sz); if (ret != 0) { // TODO: Log an error. - std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ - << std::endl; + std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ << '\n'; } } diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.h b/lib/cpp/src/thrift/async/TEvhttpServer.h index c5bf3b6eef4..aecfadef2fb 100644 --- a/lib/cpp/src/thrift/async/TEvhttpServer.h +++ b/lib/cpp/src/thrift/async/TEvhttpServer.h @@ -50,7 +50,7 @@ class TEvhttpServer { */ TEvhttpServer(std::shared_ptr processor, int port); - ~TEvhttpServer(); + virtual ~TEvhttpServer(); static void request(struct evhttp_request* req, void* self); int serve(); diff --git a/lib/cpp/src/thrift/concurrency/Mutex.h b/lib/cpp/src/thrift/concurrency/Mutex.h index 1e5c3fba37c..12f1729d6bf 100644 --- a/lib/cpp/src/thrift/concurrency/Mutex.h +++ b/lib/cpp/src/thrift/concurrency/Mutex.h @@ -20,6 +20,7 @@ #ifndef _THRIFT_CONCURRENCY_MUTEX_H_ #define _THRIFT_CONCURRENCY_MUTEX_H_ 1 +#include #include #include diff --git a/lib/cpp/src/thrift/concurrency/ThreadManager.cpp b/lib/cpp/src/thrift/concurrency/ThreadManager.cpp index e917f4a478b..a98ce00ca31 100644 --- a/lib/cpp/src/thrift/concurrency/ThreadManager.cpp +++ b/lib/cpp/src/thrift/concurrency/ThreadManager.cpp @@ -309,9 +309,9 @@ class ThreadManager::Worker : public Runnable { try { task->run(); } catch (const std::exception& e) { - GlobalOutput.printf("[ERROR] task->run() raised an exception: %s", e.what()); + TOutput::instance().printf("[ERROR] task->run() raised an exception: %s", e.what()); } catch (...) { - GlobalOutput.printf("[ERROR] task->run() raised an unknown exception"); + TOutput::instance().printf("[ERROR] task->run() raised an unknown exception"); } // Re-acquire the lock to proceed in the thread manager diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h index 7b829c76833..cba6e69485d 100644 --- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h +++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h @@ -119,6 +119,8 @@ class TBinaryProtocolT : public TVirtualProtocol::writeBinary(const std::string return TBinaryProtocolT::writeString(str); } +template +uint32_t TBinaryProtocolT::writeUUID(const TUuid& uuid) { + // TODO: Consider endian swapping, see lib/delphi/src/Thrift.Utils.pas:377 + this->trans_->write(uuid.data(), uuid.size()); + return 16; +} + /** * Reading functions */ @@ -237,7 +244,7 @@ uint32_t TBinaryProtocolT::readMessageEnd() { template uint32_t TBinaryProtocolT::readStructBegin(std::string& name) { - name = ""; + name.clear(); return 0; } @@ -286,7 +293,7 @@ uint32_t TBinaryProtocolT::readMapBegin(TType& keyType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } size = (uint32_t)sizei; - + TMap map(keyType, valType, size); checkReadBytesAvailable(map); @@ -428,6 +435,12 @@ uint32_t TBinaryProtocolT::readBinary(std::string& str) return TBinaryProtocolT::readString(str); } +template +uint32_t TBinaryProtocolT::readUUID(TUuid& uuid) { + this->trans_->readAll(uuid.begin(), uuid.size()); + return 16; +} + template template uint32_t TBinaryProtocolT::readStringBody(StrType& str, int32_t size) { @@ -456,6 +469,9 @@ uint32_t TBinaryProtocolT::readStringBody(StrType& str, return size; } + // Check against MaxMessageSize before alloc + trans_->checkReadBytesAvailable(size); + str.resize(size); this->trans_->readAll(reinterpret_cast(&str[0]), size); return (uint32_t)size; @@ -467,8 +483,8 @@ int TBinaryProtocolT::getMinSerializedSize(TType type) { switch (type) { - case T_STOP: return 0; - case T_VOID: return 0; + case T_STOP: return 1; // T_STOP needs to count itself + case T_VOID: return 1; // T_VOID needs to count itself case T_BOOL: return sizeof(int8_t); case T_BYTE: return sizeof(int8_t); case T_DOUBLE: return sizeof(double); @@ -476,10 +492,11 @@ int TBinaryProtocolT::getMinSerializedSize(TType type) case T_I32: return sizeof(int); case T_I64: return sizeof(long); case T_STRING: return sizeof(int); // string length - case T_STRUCT: return 0; // empty struct + case T_STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case T_MAP: return sizeof(int); // element count case T_SET: return sizeof(int); // element count case T_LIST: return sizeof(int); // element count + case T_UUID: return 16; // 16 bytes default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h index 792a2d89e3b..c7d81eea6e5 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h @@ -35,12 +35,12 @@ namespace protocol { template class TCompactProtocolT : public TVirtualProtocol > { public: - static const int8_t PROTOCOL_ID = (int8_t)0x82u; + static const int8_t PROTOCOL_ID = static_cast(0x82u); static const int8_t VERSION_N = 1; static const int8_t VERSION_MASK = 0x1f; // 0001 1111 protected: - static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000 + static const int8_t TYPE_MASK = static_cast(0xE0u); // 1110 0000 static const int8_t TYPE_BITS = 0x07; // 0000 0111 static const int32_t TYPE_SHIFT_AMOUNT = 5; @@ -140,6 +140,8 @@ class TCompactProtocolT : public TVirtualProtocol uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& str); + int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override @@ -213,6 +215,8 @@ class TCompactProtocolT : public TVirtualProtocol uint32_t readBinary(std::string& str); + uint32_t readUUID(TUuid& str); + /* *These methods are here for the struct to call, but don't have any wire * encoding. diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc index 9270ab89902..64162ccb0b0 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc @@ -61,10 +61,11 @@ enum Types { CT_LIST = 0x09, CT_SET = 0x0A, CT_MAP = 0x0B, - CT_STRUCT = 0x0C + CT_STRUCT = 0x0C, + CT_UUID = 0x0D }; -const int8_t TTypeToCType[16] = { +const int8_t TTypeToCType[17] = { CT_STOP, // T_STOP 0, // unused CT_BOOLEAN_TRUE, // T_BOOL @@ -81,6 +82,7 @@ const int8_t TTypeToCType[16] = { CT_MAP, // T_MAP CT_SET, // T_SET CT_LIST, // T_LIST + CT_UUID, // T_UUID }; }} // end detail::compact namespace @@ -93,7 +95,7 @@ uint32_t TCompactProtocolT::writeMessageBegin( const int32_t seqid) { uint32_t wsize = 0; wsize += writeByte(PROTOCOL_ID); - wsize += writeByte((VERSION_N & VERSION_MASK) | (((int32_t)messageType << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); + wsize += writeByte((VERSION_N & VERSION_MASK) | ((static_cast(messageType) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); wsize += writeVarint32(seqid); wsize += writeString(name); return wsize; @@ -221,7 +223,7 @@ uint32_t TCompactProtocolT::writeBool(const bool value) { template uint32_t TCompactProtocolT::writeByte(const int8_t byte) { - trans_->write((uint8_t*)&byte, 1); + trans_->write(reinterpret_cast(&byte), 1); return 1; } @@ -259,7 +261,7 @@ uint32_t TCompactProtocolT::writeDouble(const double dub) { auto bits = bitwise_cast(dub); bits = THRIFT_htolell(bits); - trans_->write((uint8_t*)&bits, 8); + trans_->write(reinterpret_cast(&bits), 8); return 8; } @@ -282,10 +284,19 @@ uint32_t TCompactProtocolT::writeBinary(const std::string& str) { if(ssize > (std::numeric_limits::max)() - wsize) throw TProtocolException(TProtocolException::SIZE_LIMIT); wsize += ssize; - trans_->write((uint8_t*)str.data(), ssize); + trans_->write(reinterpret_cast(str.data()), ssize); return wsize; } +/** + * Write a TUuid to the wire + */ +template +uint32_t TCompactProtocolT::writeUUID(const TUuid& uuid) { + trans_->write(uuid.data(), uuid.size()); + return uuid.size(); +} + // // Internal Writing methods // @@ -350,10 +361,10 @@ uint32_t TCompactProtocolT::writeVarint32(uint32_t n) { while (true) { if ((n & ~0x7F) == 0) { - buf[wsize++] = (int8_t)n; + buf[wsize++] = static_cast(n); break; } else { - buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); + buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } @@ -371,10 +382,10 @@ uint32_t TCompactProtocolT::writeVarint64(uint64_t n) { while (true) { if ((n & ~0x7FL) == 0) { - buf[wsize++] = (int8_t)n; + buf[wsize++] = static_cast(n); break; } else { - buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); + buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } @@ -431,12 +442,12 @@ uint32_t TCompactProtocolT::readMessageBegin( } rsize += readByte(versionAndType); - version = (int8_t)(versionAndType & VERSION_MASK); + version = static_cast(versionAndType & VERSION_MASK); if (version != VERSION_N) { throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version"); } - messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); + messageType = static_cast((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); rsize += readVarint32(seqid); rsize += readString(name); @@ -449,7 +460,7 @@ uint32_t TCompactProtocolT::readMessageBegin( */ template uint32_t TCompactProtocolT::readStructBegin(std::string& name) { - name = ""; + name.clear(); lastField_.push(lastFieldId_); lastFieldId_ = 0; return 0; @@ -489,12 +500,12 @@ uint32_t TCompactProtocolT::readFieldBegin(std::string& name, } // mask off the 4 MSB of the type header. it could contain a field id delta. - auto modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4); + auto modifier = static_cast(static_cast(byte & 0xf0) >> 4); if (modifier == 0) { // not a delta, look ahead for the zigzag varint field id. rsize += readI16(fieldId); } else { - fieldId = (int16_t)(lastFieldId_ + modifier); + fieldId = static_cast(lastFieldId_ + modifier); } fieldType = getTType(type); @@ -535,9 +546,9 @@ uint32_t TCompactProtocolT::readMapBegin(TType& keyType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } - keyType = getTType((int8_t)((uint8_t)kvType >> 4)); - valType = getTType((int8_t)((uint8_t)kvType & 0xf)); - size = (uint32_t)msize; + keyType = getTType(static_cast(static_cast(kvType) >> 4)); + valType = getTType(static_cast(static_cast(kvType) & 0xf)); + size = static_cast(msize); TMap map(keyType, valType, size); checkReadBytesAvailable(map); @@ -560,7 +571,7 @@ uint32_t TCompactProtocolT::readListBegin(TType& elemType, rsize += readByte(size_and_type); - lsize = ((uint8_t)size_and_type >> 4) & 0x0f; + lsize = (static_cast(size_and_type) >> 4) & 0x0f; if (lsize == 15) { rsize += readVarint32(lsize); } @@ -571,8 +582,8 @@ uint32_t TCompactProtocolT::readListBegin(TType& elemType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } - elemType = getTType((int8_t)(size_and_type & 0x0f)); - size = (uint32_t)lsize; + elemType = getTType(static_cast(size_and_type & 0x0f)); + size = static_cast(lsize); TList list(elemType, size); checkReadBytesAvailable(list); @@ -618,7 +629,7 @@ template uint32_t TCompactProtocolT::readByte(int8_t& byte) { uint8_t b[1]; trans_->readAll(b, 1); - byte = *(int8_t*)b; + byte = static_cast(b[0]); return 1; } @@ -629,7 +640,7 @@ template uint32_t TCompactProtocolT::readI16(int16_t& i16) { int32_t value; uint32_t rsize = readVarint32(value); - i16 = (int16_t)zigzagToI32(value); + i16 = static_cast(zigzagToI32(value)); return rsize; } @@ -689,7 +700,7 @@ uint32_t TCompactProtocolT::readBinary(std::string& str) { rsize += readVarint32(size); // Catch empty string case if (size == 0) { - str = ""; + str.clear(); return rsize; } @@ -701,21 +712,31 @@ uint32_t TCompactProtocolT::readBinary(std::string& str) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } + // Check against MaxMessageSize before alloc + trans_->checkReadBytesAvailable(static_cast(size)); + // Use the heap here to prevent stack overflow for v. large strings if (size > string_buf_size_ || string_buf_ == nullptr) { - void* new_string_buf = std::realloc(string_buf_, (uint32_t)size); + void* new_string_buf = std::realloc(string_buf_, static_cast(size)); if (new_string_buf == nullptr) { throw std::bad_alloc(); } - string_buf_ = (uint8_t*)new_string_buf; + string_buf_ = static_cast(new_string_buf); string_buf_size_ = size; } trans_->readAll(string_buf_, size); - str.assign((char*)string_buf_, size); + str.assign(reinterpret_cast(string_buf_), size); + + return rsize + static_cast(size); +} - trans_->checkReadBytesAvailable(rsize + (uint32_t)size); - return rsize + (uint32_t)size; +/** + * Read a TUuid from the wire. + */ +template +uint32_t TCompactProtocolT::readUUID(TUuid& uuid) { + return trans_->readAll(uuid.begin(), uuid.size()); } /** @@ -726,7 +747,7 @@ template uint32_t TCompactProtocolT::readVarint32(int32_t& i32) { int64_t val; uint32_t rsize = readVarint64(val); - i32 = (int32_t)val; + i32 = static_cast(val); return rsize; } @@ -748,7 +769,7 @@ uint32_t TCompactProtocolT::readVarint64(int64_t& i64) { while (true) { uint8_t byte = borrowed[rsize]; rsize++; - val |= (uint64_t)(byte & 0x7f) << shift; + val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; @@ -767,7 +788,7 @@ uint32_t TCompactProtocolT::readVarint64(int64_t& i64) { while (true) { uint8_t byte; rsize += trans_->readAll(&byte, 1); - val |= (uint64_t)(byte & 0x7f) << shift; + val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; @@ -825,8 +846,10 @@ TType TCompactProtocolT::getTType(int8_t type) { return T_MAP; case detail::compact::CT_STRUCT: return T_STRUCT; + case detail::compact::CT_UUID: + return T_UUID; default: - throw TException(std::string("don't know what type: ") + (char)type); + throw TException(std::string("don't know what type: ") + static_cast(type)); } } @@ -836,8 +859,8 @@ int TCompactProtocolT::getMinSerializedSize(TType type) { switch (type) { - case T_STOP: return 0; - case T_VOID: return 0; + case T_STOP: return 1; // T_STOP needs to count itself + case T_VOID: return 1; // T_VOID needs to count itself case T_BOOL: return sizeof(int8_t); case T_DOUBLE: return 8; // uses fixedLongToBytes() which always writes 8 bytes case T_BYTE: return sizeof(int8_t); @@ -845,10 +868,11 @@ int TCompactProtocolT::getMinSerializedSize(TType type) case T_I32: return sizeof(int8_t); // zigzag case T_I64: return sizeof(int8_t); // zigzag case T_STRING: return sizeof(int8_t); // string length - case T_STRUCT: return 0; // empty struct + case T_STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case T_MAP: return sizeof(int8_t); // element count case T_SET: return sizeof(int8_t); // element count case T_LIST: return sizeof(int8_t); // element count + case T_UUID: return 16; // 16 bytes default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp index 0e6d4a2aac3..6e88313db64 100644 --- a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp +++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp @@ -70,10 +70,8 @@ string TDebugProtocol::fieldTypeName(TType type) { return "set"; case T_LIST: return "list"; - case T_UTF8: - return "utf8"; - case T_UTF16: - return "utf16"; + case T_UUID: + return "uuid"; default: return "unknown"; } @@ -388,6 +386,17 @@ uint32_t TDebugProtocol::writeBinary(const string& str) { // XXX Hex? return TDebugProtocol::writeString(str); } + +uint32_t TDebugProtocol::writeUUID(const TUuid& uuid) { + size_t size = writePlain("{\n"); + indentUp(); + size += writeIndented("[raw] = "); + size += writeString(std::string(std::begin(uuid), std::end(uuid))); + size += writeIndented("[enc] = \"" + to_string(uuid) + "\"\n"); + indentDown(); + size += writeIndented("}\n"); + return size; +} } } } // apache::thrift::protocol diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.h b/lib/cpp/src/thrift/protocol/TDebugProtocol.h index 41bb0d4ec94..02662f1ab15 100644 --- a/lib/cpp/src/thrift/protocol/TDebugProtocol.h +++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.h @@ -110,6 +110,8 @@ class TDebugProtocol : public TVirtualProtocol { uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& uuid); + private: void indentUp(); void indentDown(); diff --git a/lib/cpp/src/thrift/protocol/TEnum.h b/lib/cpp/src/thrift/protocol/TEnum.h index 9636785e327..bbd1247dc19 100644 --- a/lib/cpp/src/thrift/protocol/TEnum.h +++ b/lib/cpp/src/thrift/protocol/TEnum.h @@ -18,7 +18,7 @@ */ #ifndef _THRIFT_ENUM_H_ -#define _THRIFT_ENUM_H_ +#define _THRIFT_ENUM_H_ namespace apache { namespace thrift { @@ -46,8 +46,7 @@ enum TType { T_MAP = 13, T_SET = 14, T_LIST = 15, - T_UTF8 = 16, - T_UTF16 = 17 + T_UUID = 16, }; /** @@ -63,4 +62,4 @@ enum TMessageType { }}} // apache::thrift::protocol -#endif // #define _THRIFT_ENUM_H_ +#endif // #define _THRIFT_ENUM_H_ diff --git a/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp b/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp index 6242e30b854..77d676a346f 100644 --- a/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp +++ b/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp @@ -146,6 +146,10 @@ uint32_t THeaderProtocol::writeBinary(const std::string& str) { return proto_->writeBinary(str); } +uint32_t THeaderProtocol::writeUUID(const TUuid& uuid) { + return proto_->writeUUID(uuid); +} + /** * Reading functions */ @@ -246,6 +250,10 @@ uint32_t THeaderProtocol::readString(std::string& str) { uint32_t THeaderProtocol::readBinary(std::string& binary) { return proto_->readBinary(binary); } + +uint32_t THeaderProtocol::readUUID(TUuid& uuid) { + return proto_->readUUID(uuid); +} } } } // apache::thrift::protocol diff --git a/lib/cpp/src/thrift/protocol/THeaderProtocol.h b/lib/cpp/src/thrift/protocol/THeaderProtocol.h index 0d5018596f7..99986b92c25 100644 --- a/lib/cpp/src/thrift/protocol/THeaderProtocol.h +++ b/lib/cpp/src/thrift/protocol/THeaderProtocol.h @@ -135,6 +135,8 @@ class THeaderProtocol : public TVirtualProtocol { uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& uuid); + /** * Reading functions */ @@ -181,6 +183,8 @@ class THeaderProtocol : public TVirtualProtocol { uint32_t readBinary(std::string& binary); + uint32_t readUUID(TUuid& uuid); + protected: std::shared_ptr trans_; diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp index 6e4e8ef0db6..ba20f91d64a 100644 --- a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp +++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp @@ -68,6 +68,7 @@ static const std::string kTypeNameString("str"); static const std::string kTypeNameMap("map"); static const std::string kTypeNameList("lst"); static const std::string kTypeNameSet("set"); +static const std::string kTypeNameUuid("uid"); static const std::string& getTypeNameForTypeID(TType typeID) { switch (typeID) { @@ -93,6 +94,8 @@ static const std::string& getTypeNameForTypeID(TType typeID) { return kTypeNameSet; case T_LIST: return kTypeNameList; + case T_UUID: + return kTypeNameUuid; default: throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unrecognized type"); } @@ -140,6 +143,9 @@ static TType getTypeIDForTypeName(const std::string& name) { case 't': result = T_BOOL; break; + case 'u': + result = T_UUID; + break; } } if (result == T_STOP) { @@ -710,6 +716,10 @@ uint32_t TJSONProtocol::writeBinary(const std::string& str) { return writeJSONBase64(str); } +uint32_t TJSONProtocol::writeUUID(const TUuid& uuid) { + return writeJSONString(to_string(uuid)); +} + /** * Reading functions */ @@ -801,11 +811,10 @@ uint32_t TJSONProtocol::readJSONBase64(std::string& str) { auto len = static_cast(tmp.length()); str.clear(); // Ignore padding - if (len >= 2) { - uint32_t bound = len - 2; - for (uint32_t i = len - 1; i >= bound && b[i] == '='; --i) { - --len; - } + uint32_t padding_count = 0; + while (len > 0 && b[len - 1] == '=' && padding_count < 2) { + --len; + ++padding_count; } while (len >= 4) { base64_decode(b, 4); @@ -1077,7 +1086,10 @@ uint32_t TJSONProtocol::readBool(bool& value) { uint32_t TJSONProtocol::readByte(int8_t& byte) { auto tmp = (int16_t)byte; uint32_t result = readJSONInteger(tmp); - assert(tmp < 256); + if (tmp > 127 || tmp < -128) { + throw TProtocolException(TProtocolException::INVALID_DATA, + "Expected byte value; got " + to_string(tmp)); + } byte = (int8_t)tmp; return result; } @@ -1106,14 +1118,21 @@ uint32_t TJSONProtocol::readBinary(std::string& str) { return readJSONBase64(str); } +uint32_t TJSONProtocol::readUUID(TUuid& uuid) { + std::string uuid_str; + const uint32_t result = readJSONString(uuid_str); + uuid = TUuid{uuid_str}; + return result; +} + // Return the minimum number of bytes a type will consume on the wire int TJSONProtocol::getMinSerializedSize(TType type) { switch (type) { - case T_STOP: return 0; - case T_VOID: return 0; - case T_BOOL: return 1; // written as int + case T_STOP: return 1; // T_STOP needs to count itself + case T_VOID: return 1; // T_VOID needs to count itself + case T_BOOL: return 1; // written as int case T_BYTE: return 1; case T_DOUBLE: return 1; case T_I16: return 1; @@ -1124,6 +1143,7 @@ int TJSONProtocol::getMinSerializedSize(TType type) case T_MAP: return 2; // empty map case T_SET: return 2; // empty set case T_LIST: return 2; // empty list + case T_UUID: return 16; // empty UUID default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.h b/lib/cpp/src/thrift/protocol/TJSONProtocol.h index d01bdf80141..09eb6eab1bf 100644 --- a/lib/cpp/src/thrift/protocol/TJSONProtocol.h +++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.h @@ -198,6 +198,8 @@ class TJSONProtocol : public TVirtualProtocol { uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& uuid); + /** * Reading functions */ @@ -245,6 +247,8 @@ class TJSONProtocol : public TVirtualProtocol { uint32_t readBinary(std::string& str); + uint32_t readUUID(TUuid& uuid); + int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h index 237c1e56883..63b959163d4 100644 --- a/lib/cpp/src/thrift/protocol/TProtocol.h +++ b/lib/cpp/src/thrift/protocol/TProtocol.h @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -169,8 +170,8 @@ static inline To bitwise_cast(From from) { | (((n) & 0x0000ff00ul) << 8) \ | (((n) & 0x000000fful) << 24) ) # define bswap_16(n) \ - ( (((n) & ((unsigned short)0xff00ul)) >> 8) \ - | (((n) & ((unsigned short)0x00fful)) << 8) ) + ( (((n) & static_cast(0xff00ul)) >> 8) \ + | (((n) & static_cast(0x00fful)) << 8) ) # define THRIFT_htolell(n) bswap_64(n) # define THRIFT_letohll(n) bswap_64(n) # define THRIFT_htolel(n) bswap_32(n) @@ -190,11 +191,11 @@ static inline To bitwise_cast(From from) { # define THRIFT_ntohll(n) bswap_64(n) # define THRIFT_htonll(n) bswap_64(n) # elif defined(_MSC_VER) /* Microsoft Visual C++ */ -# define THRIFT_ntohll(n) ( _byteswap_uint64((uint64_t)n) ) -# define THRIFT_htonll(n) ( _byteswap_uint64((uint64_t)n) ) +# define THRIFT_ntohll(n) ( _byteswap_uint64(static_cast(n)) ) +# define THRIFT_htonll(n) ( _byteswap_uint64(static_cast(n)) ) # elif !defined(THRIFT_ntohll) /* Not GNUC/GLIBC or MSVC */ -# define THRIFT_ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) ) -# define THRIFT_htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) ) +# define THRIFT_ntohll(n) ( (static_cast(ntohl(static_cast(n))) << 32) + ntohl(static_cast(n >> 32)) ) +# define THRIFT_htonll(n) ( (static_cast(htonl(static_cast(n))) << 32) + htonl(static_cast(n >> 32)) ) # endif /* GNUC/GLIBC or MSVC or something else */ #else /* __THRIFT_BYTE_ORDER */ # error "Can't define THRIFT_htonll or THRIFT_ntohll!" @@ -275,6 +276,8 @@ class TProtocol { virtual uint32_t writeBinary_virt(const std::string& str) = 0; + virtual uint32_t writeUUID_virt(const TUuid& uuid) = 0; + uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { @@ -382,6 +385,11 @@ class TProtocol { return writeBinary_virt(str); } + uint32_t writeUUID(const TUuid& uuid) { + T_VIRTUAL_CALL(); + return writeUUID_virt(uuid); + } + /** * Reading functions */ @@ -430,6 +438,8 @@ class TProtocol { virtual uint32_t readBinary_virt(std::string& str) = 0; + virtual uint32_t readUUID_virt(TUuid& uuid) = 0; + uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { T_VIRTUAL_CALL(); return readMessageBegin_virt(name, messageType, seqid); @@ -530,6 +540,11 @@ class TProtocol { return readBinary_virt(str); } + uint32_t readUUID(TUuid& uuid) { + T_VIRTUAL_CALL(); + return readUUID_virt(uuid); + } + /* * std::vector is specialized for bool, and its elements are individual bits * rather than bools. We need to define a different version of readBool() diff --git a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h index 5258159f149..88fbbdeb1c2 100644 --- a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h +++ b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h @@ -92,6 +92,7 @@ class TProtocolDecorator : public TProtocol { uint32_t writeDouble_virt(const double dub) override { return protocol->writeDouble(dub); } uint32_t writeString_virt(const std::string& str) override { return protocol->writeString(str); } uint32_t writeBinary_virt(const std::string& str) override { return protocol->writeBinary(str); } + uint32_t writeUUID_virt(const TUuid& uuid) override { return protocol->writeUUID(uuid); } uint32_t readMessageBegin_virt(std::string& name, TMessageType& messageType, @@ -140,6 +141,7 @@ class TProtocolDecorator : public TProtocol { uint32_t readString_virt(std::string& str) override { return protocol->readString(str); } uint32_t readBinary_virt(std::string& str) override { return protocol->readBinary(str); } + uint32_t readUUID_virt(TUuid& uuid) override { return protocol->readUUID(uuid); } private: shared_ptr protocol; diff --git a/lib/cpp/src/thrift/protocol/TProtocolTap.h b/lib/cpp/src/thrift/protocol/TProtocolTap.h index d000ba61a3b..8ceed727e16 100644 --- a/lib/cpp/src/thrift/protocol/TProtocolTap.h +++ b/lib/cpp/src/thrift/protocol/TProtocolTap.h @@ -166,6 +166,12 @@ class TProtocolTap : public TVirtualProtocol { return rv; } + uint32_t readUUID(TUuid& uuid) { + uint32_t rv = source_->readUUID(uuid); + sink_->writeUUid(uuid); + return rv; + } + private: std::shared_ptr source_; std::shared_ptr sink_; diff --git a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h index b7fe929af20..8789e473c73 100644 --- a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h +++ b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h @@ -393,6 +393,10 @@ class TVirtualProtocol : public Super_ { return static_cast(this)->writeBinary(str); } + uint32_t writeUUID_virt(const TUuid& uuid) override { + return static_cast(this)->writeUUID(uuid); + } + /** * Reading functions */ @@ -471,6 +475,10 @@ class TVirtualProtocol : public Super_ { return static_cast(this)->readBinary(str); } + uint32_t readUUID_virt(TUuid& uuid) override { + return static_cast(this)->readUUID(uuid); + } + uint32_t skip_virt(TType type) override { return static_cast(this)->skip(type); } /* diff --git a/lib/cpp/src/thrift/server/TConnectedClient.cpp b/lib/cpp/src/thrift/server/TConnectedClient.cpp index 9a78e3e9b18..18defd5eab8 100644 --- a/lib/cpp/src/thrift/server/TConnectedClient.cpp +++ b/lib/cpp/src/thrift/server/TConnectedClient.cpp @@ -75,14 +75,14 @@ void TConnectedClient::run() { // All other transport exceptions are logged. // State of connection is unknown. Done. string errStr = string("TConnectedClient died: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); done = true; break; } } } catch (const TException& tex) { string errStr = string("TConnectedClient processing exception: ") + tex.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); // Disconnect from client, because we could not process the message. done = true; } @@ -100,21 +100,21 @@ void TConnectedClient::cleanup() { inputProtocol_->getTransport()->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient input close failed: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); } try { outputProtocol_->getTransport()->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient output close failed: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); } try { client_->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient client close failed: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); } } } diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.cpp b/lib/cpp/src/thrift/server/TNonblockingServer.cpp index ae92da3afbf..d7620eb4212 100644 --- a/lib/cpp/src/thrift/server/TNonblockingServer.cpp +++ b/lib/cpp/src/thrift/server/TNonblockingServer.cpp @@ -339,21 +339,21 @@ class TNonblockingServer::TConnection::Task : public Runnable { } } } catch (const TTransportException& ttx) { - GlobalOutput.printf("TNonblockingServer: client died: %s", ttx.what()); + TOutput::instance().printf("TNonblockingServer: client died: %s", ttx.what()); } catch (const std::bad_alloc&) { - GlobalOutput("TNonblockingServer: caught bad_alloc exception."); + TOutput::instance()("TNonblockingServer: caught bad_alloc exception."); exit(1); } catch (const std::exception& x) { - GlobalOutput.printf("TNonblockingServer: process() exception: %s: %s", + TOutput::instance().printf("TNonblockingServer: process() exception: %s: %s", typeid(x).name(), x.what()); } catch (...) { - GlobalOutput.printf("TNonblockingServer: unknown exception while processing."); + TOutput::instance().printf("TNonblockingServer: unknown exception while processing."); } // Signal completion back to the libevent thread via a pipe if (!connection_->notifyIOThread()) { - GlobalOutput.printf("TNonblockingServer: failed to notifyIOThread, closing."); + TOutput::instance().printf("TNonblockingServer: failed to notifyIOThread, closing."); connection_->server_->decrementActiveProcessors(); connection_->close(); throw TException("TNonblockingServer::Task::run: failed write on notify pipe"); @@ -447,7 +447,7 @@ void TNonblockingServer::TConnection::workSocket() { //In Nonblocking SSLSocket some operations need to be retried again. //Current approach is parsing exception message, but a better solution needs to be investigated. if(!strstr(te.what(), "retry")) { - GlobalOutput.printf("TConnection::workSocket(): %s", te.what()); + TOutput::instance().printf("TConnection::workSocket(): %s", te.what()); close(); return; @@ -464,7 +464,7 @@ void TNonblockingServer::TConnection::workSocket() { if (readWant_ > server_->getMaxFrameSize()) { // Don't allow giant frame sizes. This prevents bad clients from // causing us to try and allocate a giant buffer. - GlobalOutput.printf( + TOutput::instance().printf( "TNonblockingServer: frame size too large " "(%" PRIu32 " > %" PRIu64 ") from client %s. " @@ -494,7 +494,7 @@ void TNonblockingServer::TConnection::workSocket() { case SOCKET_RECV: // It is an error to be in this state if we already have all the data if (!(readBufferPos_ < readWant_)) { - GlobalOutput.printf("TNonblockingServer: frame size too short"); + TOutput::instance().printf("TNonblockingServer: frame size too short"); close(); return; } @@ -507,7 +507,7 @@ void TNonblockingServer::TConnection::workSocket() { //In Nonblocking SSLSocket some operations need to be retried again. //Current approach is parsing exception message, but a better solution needs to be investigated. if(!strstr(te.what(), "retry")) { - GlobalOutput.printf("TConnection::workSocket(): %s", te.what()); + TOutput::instance().printf("TConnection::workSocket(): %s", te.what()); close(); } @@ -543,7 +543,7 @@ void TNonblockingServer::TConnection::workSocket() { // If there is no data to send, then let us move on if (writeBufferPos_ == writeBufferSize_) { - GlobalOutput("WARNING: Send state with no data to send"); + TOutput::instance()("WARNING: Send state with no data to send"); transition(); return; } @@ -552,7 +552,7 @@ void TNonblockingServer::TConnection::workSocket() { left = writeBufferSize_ - writeBufferPos_; sent = tSocket_->write_partial(writeBuffer_ + writeBufferPos_, left); } catch (TTransportException& te) { - GlobalOutput.printf("TConnection::workSocket(): %s ", te.what()); + TOutput::instance().printf("TConnection::workSocket(): %s ", te.what()); close(); return; } @@ -570,7 +570,7 @@ void TNonblockingServer::TConnection::workSocket() { return; default: - GlobalOutput.printf("Unexpected Socket State %d", socketState_); + TOutput::instance().printf("Unexpected Socket State %d", socketState_); assert(0); return; } @@ -635,11 +635,11 @@ void TNonblockingServer::TConnection::transition() { server_->addTask(task); } catch (IllegalStateException& ise) { // The ThreadManager is not ready to handle any more tasks (it's probably shutting down). - GlobalOutput.printf("IllegalStateException: Server::process() %s", ise.what()); + TOutput::instance().printf("IllegalStateException: Server::process() %s", ise.what()); server_->decrementActiveProcessors(); close(); } catch (TimedOutException& to) { - GlobalOutput.printf("[ERROR] TimedOutException: Server::process() %s", to.what()); + TOutput::instance().printf("[ERROR] TimedOutException: Server::process() %s", to.what()); server_->decrementActiveProcessors(); close(); } @@ -653,7 +653,7 @@ void TNonblockingServer::TConnection::transition() { // Invoke the processor processor_->process(inputProtocol_, outputProtocol_, connectionContext_); } catch (const TTransportException& ttx) { - GlobalOutput.printf( + TOutput::instance().printf( "TNonblockingServer transport error in " "process(): %s", ttx.what()); @@ -661,14 +661,14 @@ void TNonblockingServer::TConnection::transition() { close(); return; } catch (const std::exception& x) { - GlobalOutput.printf("Server::process() uncaught exception: %s: %s", + TOutput::instance().printf("Server::process() uncaught exception: %s: %s", typeid(x).name(), x.what()); server_->decrementActiveProcessors(); close(); return; } catch (...) { - GlobalOutput.printf("Server::process() unknown exception"); + TOutput::instance().printf("Server::process() unknown exception"); server_->decrementActiveProcessors(); close(); return; @@ -784,7 +784,7 @@ void TNonblockingServer::TConnection::transition() { return; default: - GlobalOutput.printf("Unexpected Application State %d", appState_); + TOutput::instance().printf("Unexpected Application State %d", appState_); assert(0); } } @@ -797,7 +797,7 @@ void TNonblockingServer::TConnection::setFlags(short eventFlags) { // Delete a previously existing event if (eventFlags_ && event_del(&event_) == -1) { - GlobalOutput.perror("TConnection::setFlags() event_del", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TConnection::setFlags() event_del", THRIFT_GET_SOCKET_ERROR); return; } @@ -841,7 +841,7 @@ void TNonblockingServer::TConnection::setFlags(short eventFlags) { // Add the event if (event_add(&event_, nullptr) == -1) { - GlobalOutput.perror("TConnection::setFlags(): could not event_add", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TConnection::setFlags(): could not event_add", THRIFT_GET_SOCKET_ERROR); } } @@ -886,8 +886,8 @@ void TNonblockingServer::TConnection::checkIdleBufferMemLimit(size_t readLimit, TNonblockingServer::~TNonblockingServer() { // Close any active connections (moves them to the idle connection stack) - while (activeConnections_.size()) { - activeConnections_.front()->close(); + while (!activeConnections_.empty()) { + (*activeConnections_.begin())->close(); } // Clean up unused TConnection objects in connectionStack_ while (!connectionStack_.empty()) { @@ -931,7 +931,8 @@ TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::share result->setSocket(socket); result->init(ioThread); } - activeConnections_.push_back(result); + + activeConnections_.insert(result); return result; } @@ -941,11 +942,7 @@ TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::share void TNonblockingServer::returnConnection(TConnection* connection) { Guard g(connMutex_); - activeConnections_.erase(std::remove(activeConnections_.begin(), - activeConnections_.end(), - connection), - activeConnections_.end()); - + activeConnections_.erase(connection); if (connectionStackLimit_ && (connectionStack_.size() >= connectionStackLimit_)) { delete connection; --numTConnections_; @@ -991,7 +988,7 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) { // Fail fast if we could not create a TConnection object if (clientConnection == nullptr) { - GlobalOutput.printf("thriftServerEventHandler: failed TConnection factory"); + TOutput::instance().printf("thriftServerEventHandler: failed TConnection factory"); clientSocket->close(); return; } @@ -1012,7 +1009,7 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) { clientConnection->transition(); } else { if (!clientConnection->notifyIOThread()) { - GlobalOutput.perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno); + TOutput::instance().perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno); clientConnection->close(); } } @@ -1045,13 +1042,13 @@ bool TNonblockingServer::serverOverloaded() { size_t activeConnections = numTConnections_ - connectionStack_.size(); if (numActiveProcessors_ > maxActiveProcessors_ || activeConnections > maxConnections_) { if (!overloaded_) { - GlobalOutput.printf("TNonblockingServer: overload condition begun."); + TOutput::instance().printf("TNonblockingServer: overload condition begun."); overloaded_ = true; } } else { if (overloaded_ && (numActiveProcessors_ <= overloadHysteresis_ * maxActiveProcessors_) && (activeConnections <= overloadHysteresis_ * maxConnections_)) { - GlobalOutput.printf( + TOutput::instance().printf( "TNonblockingServer: overload ended; " "%u dropped (%llu total)", nConnectionsDropped_, @@ -1124,7 +1121,7 @@ void TNonblockingServer::registerEvents(event_base* user_event_base) { assert(ioThreads_.size() == numIOThreads_); assert(ioThreads_.size() > 0); - GlobalOutput.printf("TNonblockingServer: Serving with %d io threads.", + TOutput::instance().printf("TNonblockingServer: Serving with %d io threads.", ioThreads_.size()); // Launch all the secondary IO threads in separate threads @@ -1163,7 +1160,7 @@ void TNonblockingServer::serve() { // Ensure all threads are finished before exiting serve() for (uint32_t i = 0; i < ioThreads_.size(); ++i) { ioThreads_[i]->join(); - GlobalOutput.printf("TNonblocking: join done for IO thread #%d", i); + TOutput::instance().printf("TNonblocking: join done for IO thread #%d", i); } } @@ -1195,7 +1192,7 @@ TNonblockingIOThread::~TNonblockingIOThread() { if (listenSocket_ != THRIFT_INVALID_SOCKET) { if (0 != ::THRIFT_CLOSESOCKET(listenSocket_)) { - GlobalOutput.perror("TNonblockingIOThread listenSocket_ close(): ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TNonblockingIOThread listenSocket_ close(): ", THRIFT_GET_SOCKET_ERROR); } listenSocket_ = THRIFT_INVALID_SOCKET; } @@ -1203,7 +1200,7 @@ TNonblockingIOThread::~TNonblockingIOThread() { for (auto notificationPipeFD : notificationPipeFDs_) { if (notificationPipeFD >= 0) { if (0 != ::THRIFT_CLOSESOCKET(notificationPipeFD)) { - GlobalOutput.perror("TNonblockingIOThread notificationPipe close(): ", + TOutput::instance().perror("TNonblockingIOThread notificationPipe close(): ", THRIFT_GET_SOCKET_ERROR); } notificationPipeFD = THRIFT_INVALID_SOCKET; @@ -1213,7 +1210,7 @@ TNonblockingIOThread::~TNonblockingIOThread() { void TNonblockingIOThread::createNotificationPipe() { if (evutil_socketpair(AF_LOCAL, SOCK_STREAM, 0, notificationPipeFDs_) == -1) { - GlobalOutput.perror("TNonblockingServer::createNotificationPipe ", EVUTIL_SOCKET_ERROR()); + TOutput::instance().perror("TNonblockingServer::createNotificationPipe ", EVUTIL_SOCKET_ERROR()); throw TException("can't create notification pipe"); } if (evutil_make_socket_nonblocking(notificationPipeFDs_[0]) < 0 @@ -1254,7 +1251,7 @@ void TNonblockingIOThread::registerEvents() { // Print some libevent stats if (number_ == 0) { - GlobalOutput.printf("TNonblockingServer: using libevent %s method %s", + TOutput::instance().printf("TNonblockingServer: using libevent %s method %s", event_get_version(), event_base_get_method(eventBase_)); } @@ -1274,7 +1271,7 @@ void TNonblockingIOThread::registerEvents() { "TNonblockingServer::serve(): " "event_add() failed on server listen event"); } - GlobalOutput.printf("TNonblocking: IO thread #%d registered for listen.", number_); + TOutput::instance().printf("TNonblocking: IO thread #%d registered for listen.", number_); } createNotificationPipe(); @@ -1295,7 +1292,7 @@ void TNonblockingIOThread::registerEvents() { "TNonblockingServer::serve(): " "event_add() failed on task-done notification event"); } - GlobalOutput.printf("TNonblocking: IO thread #%d registered for notify.", number_); + TOutput::instance().printf("TNonblocking: IO thread #%d registered for notify.", number_); } bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) { @@ -1399,18 +1396,18 @@ void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void* connection->transition(); } else if (nBytes > 0) { // throw away these bytes and hope that next time we get a solid read - GlobalOutput.printf("notifyHandler: Bad read of %d bytes, wanted %d", nBytes, kSize); + TOutput::instance().printf("notifyHandler: Bad read of %d bytes, wanted %d", nBytes, kSize); ioThread->breakLoop(true); return; } else if (nBytes == 0) { - GlobalOutput.printf("notifyHandler: Notify socket closed!"); + TOutput::instance().printf("notifyHandler: Notify socket closed!"); ioThread->breakLoop(false); // exit the loop break; } else { // nBytes < 0 if (THRIFT_GET_SOCKET_ERROR != THRIFT_EWOULDBLOCK && THRIFT_GET_SOCKET_ERROR != THRIFT_EAGAIN) { - GlobalOutput.perror("TNonblocking: notifyHandler read() failed: ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TNonblocking: notifyHandler read() failed: ", THRIFT_GET_SOCKET_ERROR); ioThread->breakLoop(true); return; } @@ -1422,10 +1419,10 @@ void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void* void TNonblockingIOThread::breakLoop(bool error) { if (error) { - GlobalOutput.printf("TNonblockingServer: IO thread #%d exiting with error.", number_); + TOutput::instance().printf("TNonblockingServer: IO thread #%d exiting with error.", number_); // TODO: figure out something better to do here, but for now kill the // whole process. - GlobalOutput.printf("TNonblockingServer: aborting process."); + TOutput::instance().printf("TNonblockingServer: aborting process."); ::abort(); } @@ -1461,9 +1458,9 @@ void TNonblockingIOThread::setCurrentThreadHighPriority(bool value) { // Actually set the sched params for the current thread. if (0 == pthread_setschedparam(pthread_self(), policy, &sp)) { - GlobalOutput.printf("TNonblocking: IO Thread #%d using high-priority scheduler!", number_); + TOutput::instance().printf("TNonblocking: IO Thread #%d using high-priority scheduler!", number_); } else { - GlobalOutput.perror("TNonblocking: pthread_setschedparam(): ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TNonblocking: pthread_setschedparam(): ", THRIFT_GET_SOCKET_ERROR); } #else THRIFT_UNUSED_VARIABLE(value); @@ -1480,7 +1477,7 @@ void TNonblockingIOThread::run() { if (eventBase_ != nullptr) { - GlobalOutput.printf("TNonblockingServer: IO thread #%d entering loop...", number_); + TOutput::instance().printf("TNonblockingServer: IO thread #%d entering loop...", number_); // Run libevent engine, never returns, invokes calls to eventHandler event_base_loop(eventBase_, 0); @@ -1492,14 +1489,14 @@ void TNonblockingIOThread::run() { cleanupEvents(); } - GlobalOutput.printf("TNonblockingServer: IO thread #%d run() done!", number_); + TOutput::instance().printf("TNonblockingServer: IO thread #%d run() done!", number_); } void TNonblockingIOThread::cleanupEvents() { // stop the listen socket, if any if (listenSocket_ != THRIFT_INVALID_SOCKET) { if (event_del(&serverEvent_) == -1) { - GlobalOutput.perror("TNonblockingIOThread::stop() event_del: ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TNonblockingIOThread::stop() event_del: ", THRIFT_GET_SOCKET_ERROR); } } diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.h b/lib/cpp/src/thrift/server/TNonblockingServer.h index 65e569dcf03..9f813ed055e 100644 --- a/lib/cpp/src/thrift/server/TNonblockingServer.h +++ b/lib/cpp/src/thrift/server/TNonblockingServer.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H #include #endif @@ -259,7 +260,7 @@ class TNonblockingServer : public TServer { * which in turn allows their transports, protocols, processors and handlers * to deallocate and clean up correctly. */ - std::vector activeConnections_; + std::unordered_set activeConnections_; /* */ diff --git a/lib/cpp/src/thrift/server/TServerFramework.cpp b/lib/cpp/src/thrift/server/TServerFramework.cpp index 2431bc2d6aa..665713a2fa5 100644 --- a/lib/cpp/src/thrift/server/TServerFramework.cpp +++ b/lib/cpp/src/thrift/server/TServerFramework.cpp @@ -101,7 +101,7 @@ static void releaseOneDescriptor(const string& name, T& pTransport) { pTransport->close(); } catch (const TTransportException& ttx) { string errStr = string("TServerFramework " + name + " close failed: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); } } } @@ -179,7 +179,7 @@ void TServerFramework::serve() { // All other transport exceptions are logged. // State of connection is unknown. Done. string errStr = string("TServerTransport died: ") + ttx.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); break; } } diff --git a/lib/cpp/src/thrift/transport/SocketCommon.cpp b/lib/cpp/src/thrift/transport/SocketCommon.cpp index 0b064c776d3..2b826e3498e 100644 --- a/lib/cpp/src/thrift/transport/SocketCommon.cpp +++ b/lib/cpp/src/thrift/transport/SocketCommon.cpp @@ -37,7 +37,7 @@ socklen_t fillUnixSocketAddr(struct sockaddr_un& address, std::string& path) #ifndef __linux__ if (isAbstractNamespace) { - GlobalOutput.perror("TSocket::open() Abstract Namespace Domain sockets only supported on linux: ", -99); + TOutput::instance().perror("TSocket::open() Abstract Namespace Domain sockets only supported on linux: ", -99); throw TTransportException(TTransportException::NOT_OPEN, " Abstract Namespace Domain socket path not supported"); } @@ -51,7 +51,7 @@ socklen_t fillUnixSocketAddr(struct sockaddr_un& address, std::string& path) if (addr_len > sizeof(((sockaddr_un*)nullptr)->sun_path)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() Unix Domain socket path too long", errno_copy); + TOutput::instance().perror("TSocket::open() Unix Domain socket path too long", errno_copy); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long"); } diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.cpp b/lib/cpp/src/thrift/transport/TBufferTransports.cpp index f7cf8f03932..a133422dbc8 100644 --- a/lib/cpp/src/thrift/transport/TBufferTransports.cpp +++ b/lib/cpp/src/thrift/transport/TBufferTransports.cpp @@ -256,8 +256,8 @@ void TFramedTransport::flush() { // Slip the frame size into the start of the buffer. sz_hbo = static_cast(wBase_ - (wBuf_.get() + sizeof(sz_nbo))); - sz_nbo = (int32_t)htonl((uint32_t)(sz_hbo)); - memcpy(wBuf_.get(), (uint8_t*)&sz_nbo, sizeof(sz_nbo)); + sz_nbo = static_cast(htonl(static_cast(sz_hbo))); + memcpy(wBuf_.get(), reinterpret_cast(&sz_nbo), sizeof(sz_nbo)); if (sz_hbo > 0) { // Note that we reset wBase_ (with a pad for the frame size) @@ -308,6 +308,8 @@ uint32_t TFramedTransport::readEnd() { setReadBuffer(rBuf_.get(), rBufSize_); } + resetConsumedMessageSize(); + return bytes_read; } @@ -347,7 +349,7 @@ uint32_t TMemoryBuffer::readAppendToString(std::string& str, uint32_t len) { computeRead(len, &start, &give); // Append to the provided string. - str.append((char*)start, give); + str.append(reinterpret_cast(start), give); return give; } diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.h b/lib/cpp/src/thrift/transport/TBufferTransports.h index f72d8f6bfda..40e2e6b6162 100644 --- a/lib/cpp/src/thrift/transport/TBufferTransports.h +++ b/lib/cpp/src/thrift/transport/TBufferTransports.h @@ -269,6 +269,11 @@ class TBufferedTransport : public TVirtualTransport // Pad the buffer so we can insert the size later. int32_t pad = 0; - this->write((uint8_t*)&pad, sizeof(pad)); + this->write(reinterpret_cast(&pad), sizeof(pad)); } std::shared_ptr transport_; @@ -463,7 +468,7 @@ class TMemoryBuffer : public TVirtualTransport { if (buf == nullptr && size != 0) { assert(owner); - buf = (uint8_t*)std::malloc(size); + buf = static_cast(std::malloc(size)); if (buf == nullptr) { throw std::bad_alloc(); } @@ -588,7 +593,7 @@ class TMemoryBuffer : public TVirtualTransport { uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); - return std::string((char*)buf, (std::string::size_type)sz); + return {reinterpret_cast(buf), static_cast(sz)}; } void appendBufferToString(std::string& str) { @@ -598,7 +603,7 @@ class TMemoryBuffer : public TVirtualTransport { uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); - str.append((char*)buf, sz); + str.append(reinterpret_cast(buf), sz); } void resetBuffer() { diff --git a/lib/cpp/src/thrift/transport/TFDTransport.h b/lib/cpp/src/thrift/transport/TFDTransport.h index fb84c9d8dbe..a9d5121a918 100644 --- a/lib/cpp/src/thrift/transport/TFDTransport.h +++ b/lib/cpp/src/thrift/transport/TFDTransport.h @@ -50,7 +50,7 @@ class TFDTransport : public TVirtualTransport { try { close(); } catch (TTransportException& ex) { - GlobalOutput.printf("~TFDTransport TTransportException: '%s'", ex.what()); + TOutput::instance().printf("~TFDTransport TTransportException: '%s'", ex.what()); } } } diff --git a/lib/cpp/src/thrift/transport/TFileTransport.cpp b/lib/cpp/src/thrift/transport/TFileTransport.cpp index dd7d22925ff..87da682f1ee 100644 --- a/lib/cpp/src/thrift/transport/TFileTransport.cpp +++ b/lib/cpp/src/thrift/transport/TFileTransport.cpp @@ -55,8 +55,6 @@ namespace transport { using std::shared_ptr; using std::cerr; -using std::cout; -using std::endl; using std::string; using namespace apache::thrift::protocol; using namespace apache::thrift::concurrency; @@ -103,10 +101,10 @@ void TFileTransport::resetOutputFile(int fd, string filename, off_t offset) { if (fd_ > 0) { // flush any events in the queue flush(); - GlobalOutput.printf("error, current file (%s) not closed", filename_.c_str()); + TOutput::instance().printf("error, current file (%s) not closed", filename_.c_str()); if (-1 == ::THRIFT_CLOSE(fd_)) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: resetOutputFile() ::close() ", errno_copy); + TOutput::instance().perror("TFileTransport: resetOutputFile() ::close() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error in file close", errno_copy); @@ -161,7 +159,7 @@ TFileTransport::~TFileTransport() { // close logfile if (fd_ > 0) { if (-1 == ::THRIFT_CLOSE(fd_)) { - GlobalOutput.perror("TFileTransport: ~TFileTransport() ::close() ", THRIFT_ERRNO); + TOutput::instance().perror("TFileTransport: ~TFileTransport() ::close() ", THRIFT_ERRNO); } else { // successfully closed fd fd_ = 0; @@ -308,7 +306,7 @@ void TFileTransport::writerThread() { openLogFile(); } catch (...) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: writerThread() openLogFile() ", errno_copy); + TOutput::instance().perror("TFileTransport: writerThread() openLogFile() ", errno_copy); fd_ = 0; hasIOError = true; } @@ -324,12 +322,12 @@ void TFileTransport::writerThread() { readState_.resetAllValues(); } else { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: writerThread() truncate ", errno_copy); + TOutput::instance().perror("TFileTransport: writerThread() truncate ", errno_copy); hasIOError = true; } } catch (...) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: writerThread() initialization ", errno_copy); + TOutput::instance().perror("TFileTransport: writerThread() initialization ", errno_copy); hasIOError = true; } } @@ -350,7 +348,7 @@ void TFileTransport::writerThread() { ::THRIFT_FSYNC(fd_); if (-1 == ::THRIFT_CLOSE(fd_)) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: writerThread() ::close() ", errno_copy); + TOutput::instance().perror("TFileTransport: writerThread() ::close() ", errno_copy); } else { // fd successfully closed fd_ = 0; @@ -428,7 +426,7 @@ void TFileTransport::writerThread() { std::unique_ptr array(zeros); if (-1 == ::THRIFT_WRITE(fd_, zeros, padding)) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: writerThread() error while padding zeros ", + TOutput::instance().perror("TFileTransport: writerThread() error while padding zeros ", errno_copy); hasIOError = true; continue; @@ -442,7 +440,7 @@ void TFileTransport::writerThread() { if (outEvent->eventSize_ > 0) { if (-1 == ::THRIFT_WRITE(fd_, outEvent->eventBuff_, outEvent->eventSize_)) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: error while writing event ", errno_copy); + TOutput::instance().perror("TFileTransport: error while writing event ", errno_copy); hasIOError = true; continue; } @@ -622,7 +620,7 @@ eventInfo* TFileTransport::readEvent() { // read error if (readState_.bufferLen_ == -1) { readState_.resetAllValues(); - GlobalOutput("TFileTransport: error while reading from file"); + TOutput::instance()("TFileTransport: error while reading from file"); throw TTransportException("TFileTransport: error while reading from file"); } else if (readState_.bufferLen_ == 0) { // EOF // wait indefinitely if there is no timeout @@ -786,7 +784,7 @@ void TFileTransport::performRecovery() { "TFileTransport: log file corrupted at offset: %lu", static_cast(offset_ + readState_.lastDispatchPtr_)); - GlobalOutput(errorMsg); + TOutput::instance()(errorMsg); throw TTransportException(errorMsg); } } @@ -831,7 +829,7 @@ void TFileTransport::seekToChunk(int32_t chunk) { readState_.resetAllValues(); currentEvent_ = nullptr; if (offset_ == -1) { - GlobalOutput("TFileTransport: lseek error in seekToChunk"); + TOutput::instance()("TFileTransport: lseek error in seekToChunk"); throw TTransportException("TFileTransport: lseek error in seekToChunk"); } @@ -900,7 +898,7 @@ void TFileTransport::openLogFile() { // make sure open call was successful if (fd_ == -1) { int errno_copy = THRIFT_ERRNO; - GlobalOutput.perror("TFileTransport: openLogFile() ::open() file: " + filename_, errno_copy); + TOutput::instance().perror("TFileTransport: openLogFile() ::open() file: " + filename_, errno_copy); throw TTransportException(TTransportException::NOT_OPEN, filename_, errno_copy); } } @@ -926,7 +924,7 @@ TFileTransportBuffer::~TFileTransportBuffer() { bool TFileTransportBuffer::addEvent(eventInfo* event) { if (bufferMode_ == READ) { - GlobalOutput("Trying to write to a buffer in read mode"); + TOutput::instance()("Trying to write to a buffer in read mode"); } if (writePoint_ < size_) { buffer_[writePoint_++] = event; @@ -1032,7 +1030,7 @@ void TFileProcessor::process(uint32_t numEvents, bool tail) { break; } } catch (TException& te) { - cerr << te.what() << endl; + cerr << te.what() << '\n'; break; } } @@ -1060,7 +1058,7 @@ void TFileProcessor::processChunk() { } catch (TEOFException&) { break; } catch (TException& te) { - cerr << te.what() << endl; + cerr << te.what() << '\n'; break; } } diff --git a/lib/cpp/src/thrift/transport/TFileTransport.h b/lib/cpp/src/thrift/transport/TFileTransport.h index 608cff18411..64aec6d455d 100644 --- a/lib/cpp/src/thrift/transport/TFileTransport.h +++ b/lib/cpp/src/thrift/transport/TFileTransport.h @@ -123,7 +123,7 @@ typedef struct readState { class TFileTransportBuffer { public: TFileTransportBuffer(uint32_t size); - ~TFileTransportBuffer(); + virtual ~TFileTransportBuffer(); bool addEvent(eventInfo* event); eventInfo* getNext(); @@ -218,7 +218,7 @@ class TFileTransport : public TFileReaderTransport, public TFileWriterTransport void setEventBufferSize(uint32_t bufferSize) { if (bufferAndThreadInitialized_) { - GlobalOutput("Cannot change the buffer size after writer thread started"); + TOutput::instance()("Cannot change the buffer size after writer thread started"); return; } eventBufferSize_ = bufferSize; diff --git a/lib/cpp/src/thrift/transport/THttpServer.cpp b/lib/cpp/src/thrift/transport/THttpServer.cpp index 91a1c39afcd..6fc2816748c 100644 --- a/lib/cpp/src/thrift/transport/THttpServer.cpp +++ b/lib/cpp/src/thrift/transport/THttpServer.cpp @@ -25,7 +25,7 @@ #include #include #if defined(_MSC_VER) || defined(__MINGW32__) - #include + #include #endif using std::string; diff --git a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp index 0e59ae47eb8..39534b74a6e 100644 --- a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp +++ b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp @@ -68,6 +68,10 @@ #endif // _WIN32 #endif +#if _WIN32 +#include +#endif + template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); @@ -172,7 +176,7 @@ bool TNonblockingServerSocket::isOpen() const { if (::THRIFT_STAT(path_.c_str(), &path_info) < 0) { #endif const std::string vError = "TNonblockingServerSocket::isOpen(): The domain socket path '" + path_ + "' does not exist (yet)."; - GlobalOutput.perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); return false; } } @@ -224,7 +228,7 @@ void TNonblockingServerSocket::_setup_sockopts() { // of the Administrators security group on Windows XP and earlier. But // we do not target WinXP anymore so no special checks required. int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, @@ -241,7 +245,7 @@ void TNonblockingServerSocket::_setup_sockopts() { cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", @@ -256,7 +260,7 @@ void TNonblockingServerSocket::_setup_sockopts() { cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", @@ -268,7 +272,7 @@ void TNonblockingServerSocket::_setup_sockopts() { struct linger ling = {0, 0}; if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&ling), sizeof(ling))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy); } @@ -276,7 +280,7 @@ void TNonblockingServerSocket::_setup_sockopts() { // Keepalive to ensure full result flushing if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_KEEPALIVE, const_cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_KEEPALIVE ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_KEEPALIVE ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", @@ -286,7 +290,7 @@ void TNonblockingServerSocket::_setup_sockopts() { #ifdef SO_NOSIGPIPE if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_NOSIGPIPE", @@ -298,7 +302,7 @@ void TNonblockingServerSocket::_setup_sockopts() { int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_GETFL failed", @@ -307,7 +311,7 @@ void TNonblockingServerSocket::_setup_sockopts() { if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_SETFL THRIFT_O_NONBLOCK failed", @@ -328,7 +332,7 @@ void TNonblockingServerSocket::_setup_tcp_sockopts() { if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", @@ -340,7 +344,7 @@ void TNonblockingServerSocket::_setup_tcp_sockopts() { if (TSocket::getUseLowMinRto()) { if (-1 == setsockopt(s, IPPROTO_TCP, TCP_LOW_MIN_RTO, const_cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() TCP_LOW_MIN_RTO ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() TCP_LOW_MIN_RTO ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", @@ -373,7 +377,7 @@ void TNonblockingServerSocket::listen() { AI_PASSIVE | AI_V4MAPPED); #endif } catch (const std::system_error& e) { - GlobalOutput.printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); + TOutput::instance().printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket."); @@ -392,7 +396,7 @@ void TNonblockingServerSocket::listen() { if (serverSocket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() socket() ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", @@ -416,7 +420,7 @@ void TNonblockingServerSocket::listen() { // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); #else - GlobalOutput.perror("TNonblockingServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); + TOutput::instance().perror("TNonblockingServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif @@ -452,7 +456,7 @@ void TNonblockingServerSocket::listen() { IPV6_V6ONLY, cast_sockopt(&zero), sizeof(zero))) { - GlobalOutput.perror("TNonblockingServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TNonblockingServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); } } #endif // #ifdef IPV6_V6ONLY @@ -472,7 +476,7 @@ void TNonblockingServerSocket::listen() { std::memset(&sa, 0, len); if (::getsockname(serverSocket_, reinterpret_cast(&sa), &len) < 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::getPort() getsockname() ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::getPort() getsockname() ", errno_copy); } else { if (sa.ss_family == AF_INET6) { const auto* sin = reinterpret_cast(&sa); @@ -487,7 +491,7 @@ void TNonblockingServerSocket::listen() { // throw error if socket still wasn't created successfully if (serverSocket_ == THRIFT_INVALID_SOCKET) { - GlobalOutput.perror("TNonblockingServerSocket::listen() socket() ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", @@ -507,7 +511,7 @@ void TNonblockingServerSocket::listen() { } else { THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() Could not bind to port %d", port_); } - GlobalOutput(errbuf); + TOutput::instance()(errbuf); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not bind", @@ -520,7 +524,7 @@ void TNonblockingServerSocket::listen() { // Call listen if (-1 == ::listen(serverSocket_, acceptBacklog_)) { errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::listen() listen() ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::listen() listen() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy); } @@ -558,7 +562,7 @@ shared_ptr TNonblockingServerSocket::acceptImpl() { if (clientSocket == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TNonblockingServerSocket::acceptImpl() ::accept() ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::acceptImpl() ::accept() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy); } @@ -567,7 +571,7 @@ shared_ptr TNonblockingServerSocket::acceptImpl() { if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); - GlobalOutput.perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); + TOutput::instance().perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_GETFL)", errno_copy); @@ -576,7 +580,7 @@ shared_ptr TNonblockingServerSocket::acceptImpl() { if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); - GlobalOutput + TOutput::instance() .perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, diff --git a/lib/cpp/src/thrift/transport/TPipe.cpp b/lib/cpp/src/thrift/transport/TPipe.cpp index a18c4f7ee34..8d02636f258 100644 --- a/lib/cpp/src/thrift/transport/TPipe.cpp +++ b/lib/cpp/src/thrift/transport/TPipe.cpp @@ -144,7 +144,7 @@ void TWaitableNamedPipeImpl::beginAsyncRead(uint8_t* buf, uint32_t len) { readOverlap_.reset(buf, len, ready_event_.h); thread_->addWorkItem(&readOverlap_); if (readOverlap_.success == FALSE && readOverlap_.last_error != ERROR_IO_PENDING) { - GlobalOutput.perror("TPipe ::ReadFile errored GLE=", readOverlap_.last_error); + TOutput::instance().perror("TPipe ::ReadFile errored GLE=", readOverlap_.last_error); throw TTransportException(TTransportException::UNKNOWN, "TPipe: ReadFile failed"); } } @@ -186,14 +186,14 @@ void pseudo_sync_write(HANDLE pipe, HANDLE event, const uint8_t* buf, uint32_t l BOOL result = ::WriteFile(pipe, buf + written, len - written, nullptr, &tempOverlap); if (result == FALSE && ::GetLastError() != ERROR_IO_PENDING) { - GlobalOutput.perror("TPipe ::WriteFile errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe ::WriteFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: write failed"); } DWORD bytes = 0; result = ::GetOverlappedResult(pipe, &tempOverlap, &bytes, TRUE); if (!result) { - GlobalOutput.perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } written += bytes; @@ -208,14 +208,14 @@ uint32_t pseudo_sync_read(HANDLE pipe, HANDLE event, uint8_t* buf, uint32_t len) BOOL result = ::ReadFile(pipe, buf, len, nullptr, &tempOverlap); if (result == FALSE && ::GetLastError() != ERROR_IO_PENDING) { - GlobalOutput.perror("TPipe ::ReadFile errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe ::ReadFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: read failed"); } DWORD bytes = 0; result = ::GetOverlappedResult(pipe, &tempOverlap, &bytes, TRUE); if (!result) { - GlobalOutput.perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } return bytes; @@ -286,13 +286,13 @@ void TPipe::open() { break; // success! if (::GetLastError() != ERROR_PIPE_BUSY) { - GlobalOutput.perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } } while (::WaitNamedPipeA(pipename_.c_str(), TimeoutSeconds_ * 1000)); if (hPipe.h == INVALID_HANDLE_VALUE) { - GlobalOutput.perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp index e4234b180b5..a99ba3bd45b 100644 --- a/lib/cpp/src/thrift/transport/TPipeServer.cpp +++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp @@ -27,8 +27,8 @@ #ifdef _WIN32 #include #include -#include -#include +#include +#include #include #endif //_WIN32 @@ -61,7 +61,7 @@ class TAnonPipeServer : public TPipeServerImpl { // pass the handles on to the client before the serve (acceptImpl) // blocking call. if (!createAnonPipe()) { - GlobalOutput.perror("TPipeServer Create(Anon)Pipe failed, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer Create(Anon)Pipe failed, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer Create(Anon)Pipe failed"); } @@ -231,7 +231,7 @@ shared_ptr TAnonPipeServer::acceptImpl() { nullptr); // not overlapped if (!fSuccess && GetLastError() != ERROR_MORE_DATA) { - GlobalOutput.perror("TPipeServer unable to initiate pipe comms, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer unable to initiate pipe comms, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer unable to initiate pipe comms"); } @@ -243,7 +243,7 @@ void TNamedPipeServer::initiateNamedConnect(const TAutoCrit &lockProof) { if (stopping_) return; if (!createNamedPipe(lockProof)) { - GlobalOutput.perror("TPipeServer CreateNamedPipe failed, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer CreateNamedPipe failed, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer CreateNamedPipe failed"); } @@ -257,7 +257,7 @@ void TNamedPipeServer::initiateNamedConnect(const TAutoCrit &lockProof) { // function returns a nonzero value. If the function returns // zero, GetLastError should return ERROR_PIPE_CONNECTED. if (connectOverlap_.success) { - GlobalOutput.printf("Client connected."); + TOutput::instance().printf("Client connected."); cached_client_.reset(new TPipe(Pipe_)); // make sure people know that a connection is ready SetEvent(listen_event_.h); @@ -267,7 +267,7 @@ void TNamedPipeServer::initiateNamedConnect(const TAutoCrit &lockProof) { DWORD dwErr = connectOverlap_.last_error; switch (dwErr) { case ERROR_PIPE_CONNECTED: - GlobalOutput.printf("Client connected."); + TOutput::instance().printf("Client connected."); cached_client_.reset(new TPipe(Pipe_)); // make sure people know that a connection is ready SetEvent(listen_event_.h); @@ -275,7 +275,7 @@ void TNamedPipeServer::initiateNamedConnect(const TAutoCrit &lockProof) { case ERROR_IO_PENDING: return; // acceptImpl will do the appropriate WaitForMultipleObjects default: - GlobalOutput.perror("TPipeServer ConnectNamedPipe failed, GLE=", dwErr); + TOutput::instance().perror("TPipeServer ConnectNamedPipe failed, GLE=", dwErr); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer ConnectNamedPipe failed"); } @@ -320,19 +320,19 @@ shared_ptr TNamedPipeServer::acceptImpl() { throw; } - GlobalOutput.perror("Client connection failed. TTransportExceptionType=", ttx.getType()); + TOutput::instance().perror("Client connection failed. TTransportExceptionType=", ttx.getType()); // kick off the next connection before throwing initiateNamedConnect(lock); throw TTransportException(TTransportException::CLIENT_DISCONNECT, ttx.what()); } - GlobalOutput.printf("Client connected."); + TOutput::instance().printf("Client connected."); // kick off the next connection before returning initiateNamedConnect(lock); return client; // success! } // if we got here, then we are in an error / shutdown case DWORD gle = GetLastError(); // save error before doing cleanup - GlobalOutput.perror("TPipeServer ConnectNamedPipe GLE=", gle); + TOutput::instance().perror("TPipeServer ConnectNamedPipe GLE=", gle); if(gle == ERROR_OPERATION_ABORTED) { TAutoCrit lock(pipe_protect_); // Needed to insure concurrent thread to be out of interrupt. throw TTransportException(TTransportException::INTERRUPTED, "TPipeServer: server interupted"); @@ -357,7 +357,7 @@ bool TNamedPipeServer::createNamedPipe(const TAutoCrit& /*lockProof*/) { if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptor_.c_str(), SDDL_REVISION_1, &psd, &size)) { DWORD lastError = GetLastError(); - GlobalOutput.perror("TPipeServer::ConvertStringSecurityDescriptorToSecurityDescriptorA() GLE=", + TOutput::instance().perror("TPipeServer::ConvertStringSecurityDescriptorToSecurityDescriptorA() GLE=", lastError); throw TTransportException( TTransportException::NOT_OPEN, @@ -387,7 +387,7 @@ bool TNamedPipeServer::createNamedPipe(const TAutoCrit& /*lockProof*/) { if (hPipe.h == INVALID_HANDLE_VALUE) { Pipe_.reset(); - GlobalOutput.perror("TPipeServer::TCreateNamedPipe() GLE=", lastError); + TOutput::instance().perror("TPipeServer::TCreateNamedPipe() GLE=", lastError); throw TTransportException(TTransportException::NOT_OPEN, "TCreateNamedPipe() failed", lastError); } @@ -401,12 +401,12 @@ bool TAnonPipeServer::createAnonPipe() { SECURITY_DESCRIPTOR sd; // security information for pipes if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { - GlobalOutput.perror("TPipeServer InitializeSecurityDescriptor (anon) failed, GLE=", + TOutput::instance().perror("TPipeServer InitializeSecurityDescriptor (anon) failed, GLE=", GetLastError()); return false; } if (!SetSecurityDescriptorDacl(&sd, true, nullptr, false)) { - GlobalOutput.perror("TPipeServer SetSecurityDescriptorDacl (anon) failed, GLE=", + TOutput::instance().perror("TPipeServer SetSecurityDescriptorDacl (anon) failed, GLE=", GetLastError()); return false; } @@ -417,12 +417,12 @@ bool TAnonPipeServer::createAnonPipe() { HANDLE ClientAnonReadH, PipeW_H, ClientAnonWriteH, Pipe_H; if (!CreatePipe(&ClientAnonReadH, &PipeW_H, &sa, 0)) // create stdin pipe { - GlobalOutput.perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); return false; } if (!CreatePipe(&Pipe_H, &ClientAnonWriteH, &sa, 0)) // create stdout pipe { - GlobalOutput.perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); + TOutput::instance().perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); CloseHandle(ClientAnonReadH); CloseHandle(PipeW_H); return false; diff --git a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp index b20c174087d..9e9fe976eaf 100644 --- a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp +++ b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp @@ -17,7 +17,7 @@ * under the License. */ -#include +//#include #include #include diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp index 26ae2beda44..db426c85ebe 100644 --- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp +++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp @@ -152,12 +152,17 @@ void cleanupOpenSSL() { #if (OPENSSL_VERSION_NUMBER < OPENSSL_ENGINE_CLEANUP_REQUIRED_BEFORE) ENGINE_cleanup(); // https://www.openssl.org/docs/man1.1.0/crypto/ENGINE_cleanup.html - cleanup call is needed before 1.1.0 #endif +#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) CONF_modules_unload(1); +#endif EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); #if OPENSSL_VERSION_NUMBER >= 0x10100000 + // Do nothing unless an openssl derivative is detected +# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); +# endif #else // ERR_remove_state() was deprecated in OpenSSL 1.0.0 and ERR_remove_thread_state() // was deprecated in OpenSSL 1.1.0; these functions and should not be used. @@ -381,21 +386,24 @@ void TSSLSocket::close() { if (rc < 0) { string errors; buildErrors(errors, errno_copy, error); - GlobalOutput(("SSL_shutdown: " + errors).c_str()); + TOutput::instance()(("SSL_shutdown: " + errors).c_str()); } } catch (TTransportException& te) { // Don't emit an exception because this method is called by the // destructor. There's also not much that a user can do to recover, so // just clean up as much as possible without throwing, similar to the rc // < 0 case above. - GlobalOutput.printf("SSL_shutdown: %s", te.what()); + TOutput::instance().printf("SSL_shutdown: %s", te.what()); } SSL_free(ssl_); ssl_ = nullptr; handshakeCompleted_ = false; #if OPENSSL_VERSION_NUMBER >= 0x10100000 + // Do nothing unless an openssl derivative is detected +# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); +# endif #else // ERR_remove_state() was deprecated in OpenSSL 1.0.0 and ERR_remove_thread_state() // was deprecated in OpenSSL 1.1.0; these functions and should not be used. @@ -601,7 +609,7 @@ void TSSLSocket::initializeHandshakeParams() { int flags; if ((flags = THRIFT_FCNTL(socket_, THRIFT_F_GETFL, 0)) < 0 || THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK) < 0) { - GlobalOutput.perror("thriftServerEventHandler: set THRIFT_O_NONBLOCK (THRIFT_FCNTL) ", + TOutput::instance().perror("thriftServerEventHandler: set THRIFT_O_NONBLOCK (THRIFT_FCNTL) ", THRIFT_GET_SOCKET_ERROR); ::THRIFT_CLOSESOCKET(socket_); return; @@ -703,7 +711,7 @@ void TSSLSocket::initializeHandshake() { } void TSSLSocket::authorize() { - int rc = SSL_get_verify_result(ssl_); + long rc = SSL_get_verify_result(ssl_); if (rc != X509_V_OK) { // verify authentication result throw TSSLException(string("SSL_get_verify_result(), ") + X509_verify_cert_error_string(rc)); } @@ -857,7 +865,7 @@ unsigned int TSSLSocket::waitForEvent(bool wantRead) { return TSSL_EINTR; // repeat operation } int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSSLSocket::read THRIFT_POLL() ", errno_copy); + TOutput::instance().perror("TSSLSocket::read THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0){ if (fds[1].revents & THRIFT_POLLIN) { @@ -873,11 +881,13 @@ unsigned int TSSLSocket::waitForEvent(bool wantRead) { uint64_t TSSLSocketFactory::count_ = 0; Mutex TSSLSocketFactory::mutex_; bool TSSLSocketFactory::manualOpenSSLInitialization_ = false; +bool TSSLSocketFactory::didWeInitializeOpenSSL_ = false; TSSLSocketFactory::TSSLSocketFactory(SSLProtocol protocol) : server_(false) { Guard guard(mutex_); if (count_ == 0) { if (!manualOpenSSLInitialization_) { + didWeInitializeOpenSSL_ = true; initializeOpenSSL(); } randomize(); @@ -890,8 +900,9 @@ TSSLSocketFactory::~TSSLSocketFactory() { Guard guard(mutex_); ctx_.reset(); count_--; - if (count_ == 0 && !manualOpenSSLInitialization_) { + if (count_ == 0 && didWeInitializeOpenSSL_) { cleanupOpenSSL(); + didWeInitializeOpenSSL_ = false; } } @@ -1123,6 +1134,10 @@ int TSSLSocketFactory::passwordCallback(char* password, int size, int, void* dat return length; } +void TSSLSocketFactory::setManualOpenSSLInitialization(bool manualOpenSSLInitialization) { + manualOpenSSLInitialization_ = manualOpenSSLInitialization; +} + // extract error messages from error queue void buildErrors(string& errors, int errno_copy, int sslerrno) { unsigned long errorCode; diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.h b/lib/cpp/src/thrift/transport/TSSLSocket.h index 5afc571f991..45502bd5ece 100644 --- a/lib/cpp/src/thrift/transport/TSSLSocket.h +++ b/lib/cpp/src/thrift/transport/TSSLSocket.h @@ -306,9 +306,8 @@ class TSSLSocketFactory { * @param manager The AccessManager instance */ virtual void access(std::shared_ptr manager) { access_ = manager; } - static void setManualOpenSSLInitialization(bool manualOpenSSLInitialization) { - manualOpenSSLInitialization_ = manualOpenSSLInitialization; - } + + static void setManualOpenSSLInitialization(bool manualOpenSSLInitialization); protected: std::shared_ptr ctx_; @@ -327,7 +326,8 @@ class TSSLSocketFactory { std::shared_ptr access_; static concurrency::Mutex mutex_; static uint64_t count_; - THRIFT_EXPORT static bool manualOpenSSLInitialization_; + static bool manualOpenSSLInitialization_; + static bool didWeInitializeOpenSSL_; // in that case we also perform de-init void setup(std::shared_ptr ssl); static int passwordCallback(char* password, int size, int, void* data); }; diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp index 7cab0eefa77..5b8bf2ec6f6 100644 --- a/lib/cpp/src/thrift/transport/TServerSocket.cpp +++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp @@ -73,9 +73,10 @@ // adds problematic macros like min() and max(). Try to work around: #define NOMINMAX #define WIN32_LEAN_AND_MEAN -#include +#include #undef NOMINMAX #undef WIN32_LEAN_AND_MEAN +#include #endif template @@ -117,7 +118,8 @@ TServerSocket::TServerSocket(int port) listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), - childInterruptSockWriter_(THRIFT_INVALID_SOCKET) { + childInterruptSockWriter_(THRIFT_INVALID_SOCKET), + boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) @@ -136,7 +138,8 @@ TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), - childInterruptSockWriter_(THRIFT_INVALID_SOCKET) { + childInterruptSockWriter_(THRIFT_INVALID_SOCKET), + boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(const string& address, int port) @@ -156,7 +159,8 @@ TServerSocket::TServerSocket(const string& address, int port) listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), - childInterruptSockWriter_(THRIFT_INVALID_SOCKET) { + childInterruptSockWriter_(THRIFT_INVALID_SOCKET), + boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(const string& path) @@ -176,7 +180,28 @@ TServerSocket::TServerSocket(const string& path) listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), - childInterruptSockWriter_(THRIFT_INVALID_SOCKET) { + childInterruptSockWriter_(THRIFT_INVALID_SOCKET), + boundSocketType_(SocketType::NONE) { +} +TServerSocket::TServerSocket(THRIFT_SOCKET sock,SocketType socketType) + : interruptableChildren_(true), + port_(0), + path_(), + serverSocket_(sock), + acceptBacklog_(DEFAULT_BACKLOG), + sendTimeout_(0), + recvTimeout_(0), + accTimeout_(-1), + retryLimit_(0), + retryDelay_(0), + tcpSendBuffer_(0), + tcpRecvBuffer_(0), + keepAlive_(false), + listening_(false), + interruptSockWriter_(THRIFT_INVALID_SOCKET), + interruptSockReader_(THRIFT_INVALID_SOCKET), + childInterruptSockWriter_(THRIFT_INVALID_SOCKET), + boundSocketType_(socketType) { } TServerSocket::~TServerSocket() { @@ -204,7 +229,7 @@ bool TServerSocket::isOpen() const { if (::THRIFT_STAT(path_.c_str(), &path_info) < 0) { #endif const std::string vError = "TServerSocket::isOpen(): The domain socket path '" + path_ + "' does not exist (yet)."; - GlobalOutput.perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); return false; } } @@ -267,7 +292,7 @@ void TServerSocket::_setup_sockopts() { // of the Administrators security group on Windows XP and earlier. But // we do not target WinXP anymore so no special checks required. int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", + TOutput::instance().perror("TServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, @@ -284,7 +309,7 @@ void TServerSocket::_setup_sockopts() { cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", @@ -299,7 +324,7 @@ void TServerSocket::_setup_sockopts() { cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", @@ -311,7 +336,7 @@ void TServerSocket::_setup_sockopts() { struct linger ling = {0, 0}; if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&ling), sizeof(ling))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy); } @@ -319,7 +344,7 @@ void TServerSocket::_setup_sockopts() { #ifdef SO_NOSIGPIPE if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_NOSIGPIPE", @@ -331,7 +356,7 @@ void TServerSocket::_setup_sockopts() { int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_GETFL failed", @@ -339,7 +364,7 @@ void TServerSocket::_setup_sockopts() { } if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_SETFL THRIFT_O_NONBLOCK failed", @@ -358,7 +383,7 @@ void TServerSocket::_setup_tcp_sockopts() { if (!isUnixDomainSocket()) { if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy); @@ -370,7 +395,7 @@ void TServerSocket::_setup_tcp_sockopts() { if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", @@ -386,7 +411,7 @@ void TServerSocket::listen() { THRIFT_SOCKET sv[2]; // Create the socket pair used to interrupt if (-1 == THRIFT_SOCKETPAIR(AF_LOCAL, SOCK_STREAM, 0, sv)) { - GlobalOutput.perror("TServerSocket::listen() socketpair() interrupt", + TOutput::instance().perror("TServerSocket::listen() socketpair() interrupt", THRIFT_GET_SOCKET_ERROR); interruptSockWriter_ = THRIFT_INVALID_SOCKET; interruptSockReader_ = THRIFT_INVALID_SOCKET; @@ -397,7 +422,7 @@ void TServerSocket::listen() { // Create the socket pair used to interrupt all clients if (-1 == THRIFT_SOCKETPAIR(AF_LOCAL, SOCK_STREAM, 0, sv)) { - GlobalOutput.perror("TServerSocket::listen() socketpair() childInterrupt", + TOutput::instance().perror("TServerSocket::listen() socketpair() childInterrupt", THRIFT_GET_SOCKET_ERROR); childInterruptSockWriter_ = THRIFT_INVALID_SOCKET; pChildInterruptSockReader_.reset(); @@ -424,7 +449,7 @@ void TServerSocket::listen() { AI_PASSIVE | AI_V4MAPPED); #endif } catch (const std::system_error& e) { - GlobalOutput.printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); + TOutput::instance().printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket."); @@ -439,11 +464,12 @@ void TServerSocket::listen() { if (isUnixDomainSocket()) { // -- Unix Domain Socket -- // - serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP); + if (serverSocket_ == THRIFT_INVALID_SOCKET) + serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP); if (serverSocket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() socket() ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", @@ -467,10 +493,12 @@ void TServerSocket::listen() { // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); #else - GlobalOutput.perror("TServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); + TOutput::instance().perror("TServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif + } else if( boundSocketType_ != SocketType::NONE){ + // -- Socket is already bound } else { // -- TCP socket -- // @@ -503,7 +531,7 @@ void TServerSocket::listen() { IPV6_V6ONLY, cast_sockopt(&zero), sizeof(zero))) { - GlobalOutput.perror("TServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); } } #endif // #ifdef IPV6_V6ONLY @@ -516,29 +544,35 @@ void TServerSocket::listen() { // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); - // retrieve bind info - if (port_ == 0 && retries <= retryLimit_) { - struct sockaddr_storage sa; - socklen_t len = sizeof(sa); - std::memset(&sa, 0, len); - if (::getsockname(serverSocket_, reinterpret_cast(&sa), &len) < 0) { - errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::getPort() getsockname() ", errno_copy); + } // TCP socket // + + // retrieve bind info + if ((port_ == 0 || path_.empty() ) && retries <= retryLimit_) { + struct sockaddr_storage sa; + socklen_t len = sizeof(sa); + std::memset(&sa, 0, len); + if (::getsockname(serverSocket_, reinterpret_cast(&sa), &len) < 0) { + errno_copy = THRIFT_GET_SOCKET_ERROR; + TOutput::instance().perror("TServerSocket::getPort() getsockname() ", errno_copy); + } else { + if (sa.ss_family == AF_INET6) { + const auto* sin = reinterpret_cast(&sa); + port_ = ntohs(sin->sin6_port); + } else if (sa.ss_family == AF_INET) { + const auto* sin = reinterpret_cast(&sa); + port_ = ntohs(sin->sin_port); + } else if (sa.ss_family == AF_UNIX) { + const auto* sin = reinterpret_cast(&sa); + path_ = sin->sun_path; } else { - if (sa.ss_family == AF_INET6) { - const auto* sin = reinterpret_cast(&sa); - port_ = ntohs(sin->sin6_port); - } else { - const auto* sin = reinterpret_cast(&sa); - port_ = ntohs(sin->sin_port); - } + TOutput::instance().perror("TServerSocket::getPort() getsockname() unhandled socket type",EINVAL); } } - } // TCP socket // + } // throw error if socket still wasn't created successfully if (serverSocket_ == THRIFT_INVALID_SOCKET) { - GlobalOutput.perror("TServerSocket::listen() socket() ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", @@ -558,7 +592,7 @@ void TServerSocket::listen() { } else { THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TServerSocket::listen() Could not bind to port %d", port_); } - GlobalOutput(errbuf); + TOutput::instance()(errbuf); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not bind", @@ -569,9 +603,9 @@ void TServerSocket::listen() { listenCallback_(serverSocket_); // Call listen - if (-1 == ::listen(serverSocket_, acceptBacklog_)) { + if (boundSocketType_ == SocketType::NONE && -1 == ::listen(serverSocket_, acceptBacklog_)) { errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy); + TOutput::instance().perror("TServerSocket::listen() listen() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy); } @@ -624,14 +658,14 @@ shared_ptr TServerSocket::acceptImpl() { continue; } int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::acceptImpl() THRIFT_POLL() ", errno_copy); + TOutput::instance().perror("TServerSocket::acceptImpl() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check for an interrupt signal if (interruptSockReader_ != THRIFT_INVALID_SOCKET && (fds[1].revents & THRIFT_POLLIN)) { int8_t buf; if (-1 == recv(interruptSockReader_, cast_sockopt(&buf), sizeof(int8_t), 0)) { - GlobalOutput.perror("TServerSocket::acceptImpl() recv() interrupt ", + TOutput::instance().perror("TServerSocket::acceptImpl() recv() interrupt ", THRIFT_GET_SOCKET_ERROR); } throw TTransportException(TTransportException::INTERRUPTED); @@ -642,7 +676,7 @@ shared_ptr TServerSocket::acceptImpl() { break; } } else { - GlobalOutput("TServerSocket::acceptImpl() THRIFT_POLL 0"); + TOutput::instance()("TServerSocket::acceptImpl() THRIFT_POLL 0"); throw TTransportException(TTransportException::UNKNOWN); } } @@ -654,7 +688,7 @@ shared_ptr TServerSocket::acceptImpl() { if (clientSocket == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TServerSocket::acceptImpl() ::accept() ", errno_copy); + TOutput::instance().perror("TServerSocket::acceptImpl() ::accept() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy); } @@ -663,7 +697,7 @@ shared_ptr TServerSocket::acceptImpl() { if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); - GlobalOutput.perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); + TOutput::instance().perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_GETFL)", errno_copy); @@ -672,7 +706,7 @@ shared_ptr TServerSocket::acceptImpl() { if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags & ~THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); - GlobalOutput + TOutput::instance() .perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, @@ -711,7 +745,7 @@ void TServerSocket::notify(THRIFT_SOCKET notifySocket) { if (notifySocket != THRIFT_INVALID_SOCKET) { int8_t byte = 0; if (-1 == send(notifySocket, cast_sockopt(&byte), sizeof(int8_t), 0)) { - GlobalOutput.perror("TServerSocket::notify() send() ", THRIFT_GET_SOCKET_ERROR); + TOutput::instance().perror("TServerSocket::notify() send() ", THRIFT_GET_SOCKET_ERROR); } } } @@ -734,7 +768,8 @@ void TServerSocket::close() { concurrency::Guard g(rwMutex_); if (serverSocket_ != THRIFT_INVALID_SOCKET) { shutdown(serverSocket_, THRIFT_SHUT_RDWR); - ::THRIFT_CLOSESOCKET(serverSocket_); + if( boundSocketType_ == SocketType::NONE) //Do not close the server socket if it owned by systemd + ::THRIFT_CLOSESOCKET(serverSocket_); } if (interruptSockWriter_ != THRIFT_INVALID_SOCKET) { ::THRIFT_CLOSESOCKET(interruptSockWriter_); diff --git a/lib/cpp/src/thrift/transport/TServerSocket.h b/lib/cpp/src/thrift/transport/TServerSocket.h index e826707ac55..4d43ccf5ade 100644 --- a/lib/cpp/src/thrift/transport/TServerSocket.h +++ b/lib/cpp/src/thrift/transport/TServerSocket.h @@ -40,6 +40,13 @@ namespace transport { class TSocket; +enum class SocketType { + NONE, + INET, + INET6, + UNIX +}; + /** * Server socket implementation of TServerTransport. Wrapper around a unix * socket listen and accept calls. @@ -82,6 +89,14 @@ class TServerSocket : public TServerTransport { */ TServerSocket(const std::string& path); + /** + * Constructor used for to initialize from an already bound unix socket. + * Useful for socket activation on systemd. + * + * @param fd + */ + TServerSocket(THRIFT_SOCKET sock,SocketType socketType); + ~TServerSocket() override; @@ -172,6 +187,7 @@ class TServerSocket : public TServerTransport { socket_func_t listenCallback_; socket_func_t acceptCallback_; + SocketType boundSocketType_; }; } } diff --git a/lib/cpp/src/thrift/transport/TSocket.cpp b/lib/cpp/src/thrift/transport/TSocket.cpp index 6c8a1c843d2..6e5727ca094 100644 --- a/lib/cpp/src/thrift/transport/TSocket.cpp +++ b/lib/cpp/src/thrift/transport/TSocket.cpp @@ -63,6 +63,10 @@ #endif // _WIN32 #endif +#if _WIN32 +#include +#endif + template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); @@ -197,7 +201,7 @@ bool TSocket::hasPendingDataToRead() { if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { goto try_again; } - GlobalOutput.perror("TSocket::hasPendingDataToRead() THRIFT_IOCTL_SOCKET() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::hasPendingDataToRead() THRIFT_IOCTL_SOCKET() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } return numBytesAvailable > 0; @@ -226,7 +230,7 @@ bool TSocket::peek() { if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { continue; } - GlobalOutput.perror("TSocket::peek() THRIFT_POLL() ", errno_copy); + TOutput::instance().perror("TSocket::peek() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check the interruptListener @@ -256,7 +260,7 @@ bool TSocket::peek() { return false; } #endif - GlobalOutput.perror("TSocket::peek() recv() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::peek() recv() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::UNKNOWN, "recv()", errno_copy); } return (r > 0); @@ -276,7 +280,7 @@ void TSocket::openConnection(struct addrinfo* res) { if (socket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() socket() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() socket() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "socket()", errno_copy); } @@ -320,13 +324,13 @@ void TSocket::openConnection(struct addrinfo* res) { if (connTimeout_ > 0) { if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() THRIFT_FCNTL() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() THRIFT_FCNTL() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } } else { if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags & ~THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } } @@ -342,7 +346,7 @@ void TSocket::openConnection(struct addrinfo* res) { ret = connect(socket_, (struct sockaddr*)&address, structlen); #else - GlobalOutput.perror("TSocket::open() Unix Domain socket path not supported on this version of Windows", -99); + TOutput::instance().perror("TSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif @@ -358,7 +362,7 @@ void TSocket::openConnection(struct addrinfo* res) { if ((THRIFT_GET_SOCKET_ERROR != THRIFT_EINPROGRESS) && (THRIFT_GET_SOCKET_ERROR != THRIFT_EWOULDBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() connect() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() connect() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "connect() failed", errno_copy); } @@ -376,25 +380,25 @@ void TSocket::openConnection(struct addrinfo* res) { int ret2 = getsockopt(socket_, SOL_SOCKET, SO_ERROR, cast_sockopt(&val), &lon); if (ret2 == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() getsockopt() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() getsockopt() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "getsockopt()", errno_copy); } // no errors on socket, go to town if (val == 0) { goto done; } - GlobalOutput.perror("TSocket::open() error on socket (after THRIFT_POLL) " + getSocketInfo(), + TOutput::instance().perror("TSocket::open() error on socket (after THRIFT_POLL) " + getSocketInfo(), val); throw TTransportException(TTransportException::NOT_OPEN, "socket open() error", val); } else if (ret == 0) { // socket timed out string errStr = "TSocket::open() timed out " + getSocketInfo(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); throw TTransportException(TTransportException::NOT_OPEN, "open() timed out"); } else { // error on THRIFT_POLL() int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() THRIFT_POLL() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() THRIFT_POLL() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_POLL() failed", errno_copy); } @@ -402,7 +406,7 @@ void TSocket::openConnection(struct addrinfo* res) { // Set socket back to normal mode (blocking) if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } @@ -461,7 +465,9 @@ void TSocket::local_open() { #ifdef _WIN32 error == WSANO_DATA #else - error == EAI_NODATA + // to support systems with no ipv4 addresses but using "127.0.0.1" as a hostname + // getaddrinfo() fails when AI_ADDRCONFIG is present in this situation... + error == EAI_NODATA || error == EAI_ADDRFAMILY #endif ) { hints.ai_flags &= ~AI_ADDRCONFIG; @@ -471,7 +477,7 @@ void TSocket::local_open() { if (error) { string errStr = "TSocket::open() getaddrinfo() " + getSocketInfo() + string(THRIFT_GAI_STRERROR(error)); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for client socket."); @@ -561,7 +567,7 @@ uint32_t TSocket::read(uint8_t* buf, uint32_t len) { if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { goto try_again; } - GlobalOutput.perror("TSocket::read() THRIFT_POLL() ", errno_copy); + TOutput::instance().perror("TSocket::read() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check the interruptListener @@ -569,7 +575,7 @@ uint32_t TSocket::read(uint8_t* buf, uint32_t len) { throw TTransportException(TTransportException::INTERRUPTED, "Interrupted"); } } else /* ret == 0 */ { - GlobalOutput.printf("TSocket::read() THRIFT_EAGAIN (timed out) after %d ms", recvTimeout_); + TOutput::instance().printf("TSocket::read() THRIFT_EAGAIN (timed out) after %d ms", recvTimeout_); throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (timed out)"); } @@ -628,7 +634,7 @@ uint32_t TSocket::read(uint8_t* buf, uint32_t len) { } // Now it's not a try again case, but a real probblez - GlobalOutput.perror("TSocket::read() recv() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::read() recv() " + getSocketInfo(), errno_copy); // Some other error, whatevz throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); @@ -673,7 +679,7 @@ uint32_t TSocket::write_partial(const uint8_t* buf, uint32_t len) { } // Fail on a send error int errno_copy = THRIFT_GET_SOCKET_ERROR; - GlobalOutput.perror("TSocket::write_partial() send() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::write_partial() send() " + getSocketInfo(), errno_copy); if (errno_copy == THRIFT_EPIPE || errno_copy == THRIFT_ECONNRESET || errno_copy == THRIFT_ENOTCONN) { @@ -735,7 +741,7 @@ void TSocket::setLinger(bool on, int linger) { if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. - GlobalOutput.perror("TSocket::setLinger() setsockopt() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::setLinger() setsockopt() " + getSocketInfo(), errno_copy); } } @@ -751,7 +757,7 @@ void TSocket::setNoDelay(bool noDelay) { if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. - GlobalOutput.perror("TSocket::setNoDelay() setsockopt() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::setNoDelay() setsockopt() " + getSocketInfo(), errno_copy); } } @@ -763,7 +769,7 @@ void setGenericTimeout(THRIFT_SOCKET s, int timeout_ms, int optname) { if (timeout_ms < 0) { char errBuf[512]; sprintf(errBuf, "TSocket::setGenericTimeout with negative input: %d\n", timeout_ms); - GlobalOutput(errBuf); + TOutput::instance()(errBuf); return; } @@ -781,7 +787,7 @@ void setGenericTimeout(THRIFT_SOCKET s, int timeout_ms, int optname) { if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. - GlobalOutput.perror("TSocket::setGenericTimeout() setsockopt() ", errno_copy); + TOutput::instance().perror("TSocket::setGenericTimeout() setsockopt() ", errno_copy); } } @@ -816,7 +822,7 @@ void TSocket::setKeepAlive(bool keepAlive) { if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. - GlobalOutput.perror("TSocket::setKeepAlive() setsockopt() " + getSocketInfo(), errno_copy); + TOutput::instance().perror("TSocket::setKeepAlive() setsockopt() " + getSocketInfo(), errno_copy); } } diff --git a/lib/cpp/src/thrift/transport/TSocketPool.cpp b/lib/cpp/src/thrift/transport/TSocketPool.cpp index f56c76ee458..5c3aa4e2b01 100644 --- a/lib/cpp/src/thrift/transport/TSocketPool.cpp +++ b/lib/cpp/src/thrift/transport/TSocketPool.cpp @@ -79,7 +79,7 @@ TSocketPool::TSocketPool(const vector& hosts, const vector& ports) randomize_(true), alwaysTryLast_(true) { if (hosts.size() != ports.size()) { - GlobalOutput("TSocketPool::TSocketPool: hosts.size != ports.size"); + TOutput::instance()("TSocketPool::TSocketPool: hosts.size != ports.size"); throw TTransportException(TTransportException::BAD_ARGS); } @@ -229,7 +229,7 @@ void TSocketPool::open() { TSocket::open(); } catch (const TException &e) { string errStr = "TSocketPool::open failed " + getSocketInfo() + ": " + e.what(); - GlobalOutput(errStr.c_str()); + TOutput::instance()(errStr.c_str()); socket_ = THRIFT_INVALID_SOCKET; continue; } @@ -251,7 +251,7 @@ void TSocketPool::open() { } } - GlobalOutput("TSocketPool::open: all connections failed"); + TOutput::instance()("TSocketPool::open: all connections failed"); throw TTransportException(TTransportException::NOT_OPEN); } diff --git a/lib/cpp/src/thrift/transport/TSocketUtils.h b/lib/cpp/src/thrift/transport/TSocketUtils.h index c9e0e57b882..b00fd342c5d 100644 --- a/lib/cpp/src/thrift/transport/TSocketUtils.h +++ b/lib/cpp/src/thrift/transport/TSocketUtils.h @@ -62,7 +62,13 @@ struct AddressResolutionHelper { public: using PtrOwnedList = std::unique_ptr; - struct Iter : std::iterator { + struct Iter { + using iterator_category = std::forward_iterator_tag; + using value_type = const addrinfo*; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + value_type ptr = nullptr; Iter() = default; diff --git a/lib/cpp/src/thrift/transport/TTransport.h b/lib/cpp/src/thrift/transport/TTransport.h index 52b3a0a4d32..1158bcf04d2 100644 --- a/lib/cpp/src/thrift/transport/TTransport.h +++ b/lib/cpp/src/thrift/transport/TTransport.h @@ -274,7 +274,7 @@ class TTransport { */ void checkReadBytesAvailable(long int numBytes) { - if (remainingMessageSize_ < numBytes) + if (remainingMessageSize_ < numBytes || numBytes < 0) throw TTransportException(TTransportException::END_OF_FILE, "MaxMessageSize reached"); } diff --git a/lib/cpp/src/thrift/transport/TWebSocketServer.h b/lib/cpp/src/thrift/transport/TWebSocketServer.h index 7f39f36b95e..2a3e076cf04 100644 --- a/lib/cpp/src/thrift/transport/TWebSocketServer.h +++ b/lib/cpp/src/thrift/transport/TWebSocketServer.h @@ -31,7 +31,7 @@ #include #include #if defined(_MSC_VER) || defined(__MINGW32__) -#include +#include #define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle) #else diff --git a/lib/cpp/src/thrift/transport/TZlibTransport.cpp b/lib/cpp/src/thrift/transport/TZlibTransport.cpp index 657ce52052d..1a171109837 100644 --- a/lib/cpp/src/thrift/transport/TZlibTransport.cpp +++ b/lib/cpp/src/thrift/transport/TZlibTransport.cpp @@ -83,7 +83,7 @@ inline void TZlibTransport::checkZlibRvNothrow(int status, const char* message) if (status != Z_OK) { string output = "TZlibTransport: zlib failure in destructor: " + TZlibTransportException::errorMessage(status, message); - GlobalOutput(output.c_str()); + TOutput::instance()(output.c_str()); } } diff --git a/lib/cpp/src/thrift/windows/Operators.h b/lib/cpp/src/thrift/windows/Operators.h index 9b860968002..406e11eb6ec 100644 --- a/lib/cpp/src/thrift/windows/Operators.h +++ b/lib/cpp/src/thrift/windows/Operators.h @@ -29,11 +29,6 @@ namespace thrift { class TEnumIterator; -inline bool operator==(const TEnumIterator&, const TEnumIterator&) { - // Not entirely sure what the test should be here. It is only to enable - // iterator debugging and is not used in release mode. - return true; -} } } // apache::thrift diff --git a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp index 02beec7eec4..cbfd96f155e 100644 --- a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp +++ b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp @@ -52,7 +52,7 @@ uint32_t TOverlappedWorkItem::overlappedResults(bool signal_failure) { BOOL result = ::GetOverlappedResult(h, &overlap, &bytes, TRUE); if (signal_failure && !result) // get overlapped error case { - GlobalOutput.perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); + TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } return bytes; @@ -113,7 +113,7 @@ TOverlappedSubmissionThread::TOverlappedSubmissionThread() { InitializeSListHead(&workList_); thread_ = (HANDLE)_beginthreadex(NULL, 0, thread_proc, this, 0, NULL); if (thread_ == 0) { - GlobalOutput.perror("TOverlappedSubmissionThread unable to create thread, errno=", errno); + TOutput::instance().perror("TOverlappedSubmissionThread unable to create thread, errno=", errno); throw TTransportException(TTransportException::NOT_OPEN, " TOverlappedSubmissionThread unable to create thread"); } diff --git a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h index 057f623b99a..7326a9c0e28 100644 --- a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h +++ b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h @@ -105,7 +105,7 @@ class TOverlappedSubmissionThread : apache::thrift::TNonCopyable { // thread details private: TOverlappedSubmissionThread(); - ~TOverlappedSubmissionThread(); + virtual ~TOverlappedSubmissionThread(); void run(); static unsigned __stdcall thread_proc(void* addr); @@ -122,7 +122,7 @@ class TAutoOverlapThread : apache::thrift::TNonCopyable { public: TAutoOverlapThread() : p(TOverlappedSubmissionThread::acquire_instance()) {} - ~TAutoOverlapThread() { TOverlappedSubmissionThread::release_instance(); } + virtual ~TAutoOverlapThread() { TOverlappedSubmissionThread::release_instance(); } TOverlappedSubmissionThread* operator->() { return p; } }; } diff --git a/lib/cpp/src/thrift/windows/SocketPair.cpp b/lib/cpp/src/thrift/windows/SocketPair.cpp index 2650b37d475..9271b02943b 100644 --- a/lib/cpp/src/thrift/windows/SocketPair.cpp +++ b/lib/cpp/src/thrift/windows/SocketPair.cpp @@ -34,7 +34,7 @@ #include // Win32 -#include +#include int thrift_socketpair(int d, int type, int protocol, THRIFT_SOCKET sv[2]) { THRIFT_UNUSED_VARIABLE(protocol); diff --git a/lib/cpp/src/thrift/windows/Sync.h b/lib/cpp/src/thrift/windows/Sync.h index a5b2ac50f0d..ab0992520e2 100644 --- a/lib/cpp/src/thrift/windows/Sync.h +++ b/lib/cpp/src/thrift/windows/Sync.h @@ -37,7 +37,7 @@ #define WIN32_LEAN_AND_MEAN #define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif -#include +#include #ifdef _THRIFT_UNDEF_NOMINMAX #undef NOMINMAX #undef _THRIFT_UNDEF_NOMINMAX @@ -58,7 +58,7 @@ namespace thrift { struct TCriticalSection : apache::thrift::TNonCopyable { CRITICAL_SECTION cs; TCriticalSection() { InitializeCriticalSection(&cs); } - ~TCriticalSection() { DeleteCriticalSection(&cs); } + virtual ~TCriticalSection() { DeleteCriticalSection(&cs); } }; class TAutoCrit : apache::thrift::TNonCopyable { @@ -67,7 +67,7 @@ class TAutoCrit : apache::thrift::TNonCopyable { public: explicit TAutoCrit(TCriticalSection& cs) : cs_(&cs.cs) { EnterCriticalSection(cs_); } - ~TAutoCrit() { LeaveCriticalSection(cs_); } + virtual ~TAutoCrit() { LeaveCriticalSection(cs_); } }; struct TAutoResetEvent : apache::thrift::TNonCopyable { @@ -76,11 +76,11 @@ struct TAutoResetEvent : apache::thrift::TNonCopyable { TAutoResetEvent() { h = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (h == nullptr) { - GlobalOutput.perror("TAutoResetEvent unable to create event, GLE=", GetLastError()); + TOutput::instance().perror("TAutoResetEvent unable to create event, GLE=", GetLastError()); throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } - ~TAutoResetEvent() { CloseHandle(h); } + virtual ~TAutoResetEvent() { CloseHandle(h); } }; struct TManualResetEvent : apache::thrift::TNonCopyable { @@ -89,11 +89,11 @@ struct TManualResetEvent : apache::thrift::TNonCopyable { TManualResetEvent() { h = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (h == nullptr) { - GlobalOutput.perror("TManualResetEvent unable to create event, GLE=", GetLastError()); + TOutput::instance().perror("TManualResetEvent unable to create event, GLE=", GetLastError()); throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } - ~TManualResetEvent() { CloseHandle(h); } + virtual ~TManualResetEvent() { CloseHandle(h); } }; struct TAutoHandle : apache::thrift::TNonCopyable { diff --git a/lib/cpp/src/thrift/windows/TWinsockSingleton.h b/lib/cpp/src/thrift/windows/TWinsockSingleton.h index a098d2c7144..a8e517aabb9 100644 --- a/lib/cpp/src/thrift/windows/TWinsockSingleton.h +++ b/lib/cpp/src/thrift/windows/TWinsockSingleton.h @@ -54,7 +54,7 @@ class TWinsockSingleton : private apache::thrift::TNonCopyable { TWinsockSingleton(void); public: - ~TWinsockSingleton(void); + virtual ~TWinsockSingleton(void); public: static void create(void); diff --git a/lib/cpp/src/thrift/windows/config.h b/lib/cpp/src/thrift/windows/config.h index 19296d63f30..2fc6458f009 100644 --- a/lib/cpp/src/thrift/windows/config.h +++ b/lib/cpp/src/thrift/windows/config.h @@ -52,7 +52,6 @@ #include #include #include -#include #include #include diff --git a/lib/cpp/test/AllProtocolTests.tcc b/lib/cpp/test/AllProtocolTests.tcc index 80a4ea097ab..cb98917d3ea 100644 --- a/lib/cpp/test/AllProtocolTests.tcc +++ b/lib/cpp/test/AllProtocolTests.tcc @@ -25,6 +25,7 @@ #include #include #include +#include #include "GenericHelpers.h" @@ -208,6 +209,9 @@ void testProtocol(const char* protoname) { testNaked("a bit longer than the smallest possible"); testNaked("\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA"); // kinda binary test + testNaked(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + testField(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + testField(""); testField("short"); testField("borderlinetiny"); diff --git a/lib/cpp/test/Benchmark.cpp b/lib/cpp/test/Benchmark.cpp index 56adac0b203..22ec86c54a6 100644 --- a/lib/cpp/test/Benchmark.cpp +++ b/lib/cpp/test/Benchmark.cpp @@ -53,7 +53,6 @@ int main() { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using std::cout; - using std::endl; OneOfEach ooe; ooe.im_true = true; @@ -66,6 +65,7 @@ int main() { ooe.some_characters = "JSON THIS! \"\1"; ooe.zomg_unicode = "\xd7\n\a\t"; ooe.base64 = "\1\2\3\255"; + ooe.rfc4122_uuid = apache::thrift::TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}; int num = 100000; std::shared_ptr buf(new TMemoryBuffer(num*1000)); @@ -83,7 +83,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); @@ -99,7 +99,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -112,7 +112,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -126,7 +126,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -139,7 +139,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -153,7 +153,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } @@ -176,7 +176,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); @@ -190,7 +190,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -201,7 +201,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -213,7 +213,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -224,7 +224,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -236,7 +236,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt index 1117cd9f36a..3ed1d202668 100644 --- a/lib/cpp/test/CMakeLists.txt +++ b/lib/cpp/test/CMakeLists.txt @@ -47,6 +47,8 @@ set(testgencpp_SOURCES gen-cpp/OneWayService.h gen-cpp/TypedefTest_types.cpp gen-cpp/TypedefTest_types.h + gen-cpp/Thrift5272_types.cpp + gen-cpp/Thrift5272_types.h ThriftTest_extras.cpp DebugProtoTest_extras.cpp ) @@ -65,6 +67,11 @@ set(testgencpp_cob_SOURCES ) add_library(testgencpp_cob STATIC ${testgencpp_cob_SOURCES}) +if (WIN32 AND MSVC) + add_library(testgencppCLI STATIC ${testgencpp_SOURCES}) + set_target_properties(testgencppCLI PROPERTIES COMMON_LANGUAGE_RUNTIME "") +endif() + add_executable(Benchmark Benchmark.cpp) target_link_libraries(Benchmark testgencpp) target_link_libraries(Benchmark thrift) @@ -82,6 +89,8 @@ set(UnitTest_SOURCES TServerSocketTest.cpp TServerTransportTest.cpp ThrifttReadCheckTests.cpp + TUuidTest.cpp + Thrift5272.cpp ) add_executable(UnitTests ${UnitTest_SOURCES}) @@ -94,6 +103,25 @@ if(MSVC) set_property( TARGET UnitTests APPEND_STRING PROPERTY COMPILE_FLAGS /wd4503 ) endif() +# Test the THRIFT_TUUID_SUPPORT_BOOST_UUID compiler directive globally set on the target +add_executable(UnitTestsUuid + UnitTestMain.cpp + TUuidTestBoost.cpp +) +target_link_libraries(UnitTestsUuid testgencpp ${Boost_LIBRARIES}) +target_link_libraries(UnitTestsUuid thrift) +target_compile_definitions(UnitTestsUuid PUBLIC THRIFT_TUUID_SUPPORT_BOOST_UUID) +add_test(NAME UnitTestsUuid COMMAND UnitTestsUuid) + +# Test not setting the THRIFT_TUUID_SUPPORT_BOOST_UUID compiler directive as with the test above. +# The test does set the directive before including the thrift header to test the behaviour +add_executable(UnitTestsUuidNoDirective + UnitTestMain.cpp + TUuidTestBoostNoDirective.cpp +) +target_link_libraries(UnitTestsUuidNoDirective testgencpp ${Boost_LIBRARIES}) +target_link_libraries(UnitTestsUuidNoDirective thrift) +add_test(NAME UnitTestsUuidNoDirective COMMAND UnitTestsUuidNoDirective) set( TInterruptTest_SOURCES TSocketInterruptTest.cpp @@ -110,7 +138,7 @@ target_link_libraries(TInterruptTest ${Boost_LIBRARIES} ) target_link_libraries(TInterruptTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(TInterruptTest -lrt) endif () add_test(NAME TInterruptTest COMMAND TInterruptTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -121,7 +149,7 @@ target_link_libraries(TServerIntegrationTest ${Boost_LIBRARIES} ) target_link_libraries(TServerIntegrationTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(TServerIntegrationTest -lrt) endif () add_test(NAME TServerIntegrationTest COMMAND TServerIntegrationTest) @@ -324,7 +352,7 @@ target_link_libraries(SecurityTest ${Boost_LIBRARIES} ) target_link_libraries(SecurityTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(SecurityTest -lrt) endif () add_test(NAME SecurityTest COMMAND SecurityTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -335,7 +363,7 @@ target_link_libraries(SecurityFromBufferTest ${Boost_LIBRARIES} ) target_link_libraries(SecurityFromBufferTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(SecurityFromBufferTest -lrt) endif () add_test(NAME SecurityFromBufferTest COMMAND SecurityFromBufferTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -349,6 +377,8 @@ endif() # # Common thrift code generation rules # +# files from /test +# add_custom_command(OUTPUT gen-cpp/AnnotationTest_constants.cpp gen-cpp/AnnotationTest_constants.h @@ -360,7 +390,7 @@ add_custom_command(OUTPUT gen-cpp/AnnotationTest_constants.cpp ) add_custom_command(OUTPUT gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/DebugProtoTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift ) add_custom_command(OUTPUT gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h @@ -384,13 +414,19 @@ add_custom_command(OUTPUT gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp ) add_custom_command(OUTPUT gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift ) +# files from /lib/cpp/test + add_custom_command(OUTPUT gen-cpp/OneWayService.cpp gen-cpp/OneWayTest_types.h gen-cpp/OneWayService.h COMMAND ${THRIFT_COMPILER} --gen cpp ${CMAKE_CURRENT_SOURCE_DIR}/OneWayTest.thrift ) +add_custom_command(OUTPUT gen-cpp/Thrift5272_types.cpp gen-cpp/Thrift5272_types.h + COMMAND ${THRIFT_COMPILER} --gen cpp ${CMAKE_CURRENT_SOURCE_DIR}/Thrift5272.thrift +) + add_custom_command(OUTPUT gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style ${CMAKE_CURRENT_SOURCE_DIR}/processor/proc.thrift ) diff --git a/lib/cpp/test/DebugProtoTest.cpp b/lib/cpp/test/DebugProtoTest.cpp index 060f3547dd7..1a56e7edee2 100644 --- a/lib/cpp/test/DebugProtoTest.cpp +++ b/lib/cpp/test/DebugProtoTest.cpp @@ -74,6 +74,12 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_1) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\",\n" + " [enc] = \"00000000-0000-0000-0000-000000000000\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[0] {\n" + " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(*ooe)); @@ -84,6 +90,8 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_1) { static ::std::shared_ptr n; void testCaseSetup_2() { + using apache::thrift::TUuid; + testCaseSetup_1(); n.reset(new Nesting); @@ -98,8 +106,14 @@ void testCaseSetup_2() { "\xb0\xcf\x81\xe2\x84\x8e\x20\xce\x91\x74\x74" "\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80" "\xbc"; + n->my_ooe.rfc4122_uuid = TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}; n->my_bonk.type = 31337; n->my_bonk.message = "I am a bonk... xor!"; + + std::vector uuiid_list; + uuiid_list.push_back(TUuid{"{fa1af5ec-fdc2-4355-844a-9f0dbfd00e50}"}); + uuiid_list.push_back(TUuid{"{1beece83-34f4-4fa3-b757-1ad1ac157fe3}"}); + n->my_ooe.rfc4122_uuid_list = uuiid_list; } BOOST_AUTO_TEST_CASE(test_debug_proto_2) { @@ -141,6 +155,20 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_2) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"^*\\xb1\\x88\\x17&Nu\\xa0O\\x1e\\xd9\\xa6\\xa8\\x9cL\",\n" + " [enc] = \"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[2] {\n" + "{\n" + " [raw] = [0] = \"\\xfa\\x1a\\xf5\\xec\\xfd\\xc2CU\\x84J\\x9f\\r\\xbf\\xd0\\x0eP\",\n" + " [enc] = \"fa1af5ec-fdc2-4355-844a-9f0dbfd00e50\"\n" + " }\n" + "{\n" + " [raw] = [1] = \"\\x1b\\xee\\xce\\x834\\xf4O\\xa3\\xb7W\\x1a\\xd1\\xac\\x15\\x7f\\xe3\",\n" + " [enc] = \"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"\n" + " }\n" + " },\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(*n)); @@ -228,6 +256,12 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_3) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\",\n" + " [enc] = \"00000000-0000-0000-0000-000000000000\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[0] {\n" + " },\n" " },\n" " [1] = OneOfEach {\n" " 01: im_true (bool) = true,\n" @@ -259,6 +293,20 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_3) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"^*\\xb1\\x88\\x17&Nu\\xa0O\\x1e\\xd9\\xa6\\xa8\\x9cL\",\n" + " [enc] = \"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[2] {\n" + "{\n" + " [raw] = [0] = \"\\xfa\\x1a\\xf5\\xec\\xfd\\xc2CU\\x84J\\x9f\\r\\xbf\\xd0\\x0eP\",\n" + " [enc] = \"fa1af5ec-fdc2-4355-844a-9f0dbfd00e50\"\n" + " }\n" + "{\n" + " [raw] = [1] = \"\\x1b\\xee\\xce\\x834\\xf4O\\xa3\\xb7W\\x1a\\xd1\\xac\\x15\\x7f\\xe3\",\n" + " [enc] = \"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"\n" + " }\n" + " },\n" " },\n" " },\n" " 02: contain (set) = set[3] {\n" diff --git a/lib/cpp/test/GenericHelpers.h b/lib/cpp/test/GenericHelpers.h index bcef9f24252..1eed4e2b517 100644 --- a/lib/cpp/test/GenericHelpers.h +++ b/lib/cpp/test/GenericHelpers.h @@ -23,6 +23,7 @@ #include #include #include +#include /* ClassName Helper for cleaner exceptions */ class ClassNames { @@ -57,6 +58,10 @@ template <> const char* ClassNames::getName() { return "string"; } +template <> +const char* ClassNames::getName() { + return "uuid"; +} /* Generic Protocol I/O function for tests */ class GenericIO { @@ -87,6 +92,10 @@ class GenericIO { return proto->writeString(val); } + static uint32_t write(std::shared_ptr proto, const apache::thrift::TUuid& val) { + return proto->writeUUID(val); + } + /* Read functions */ static uint32_t read(std::shared_ptr proto, int8_t& val) { return proto->readByte(val); } @@ -102,6 +111,10 @@ class GenericIO { static uint32_t read(std::shared_ptr proto, std::string& val) { return proto->readString(val); } + + static uint32_t read(std::shared_ptr proto, apache::thrift::TUuid& val) { + return proto->readUUID(val); + } }; #endif diff --git a/lib/cpp/test/JSONProtoTest.cpp b/lib/cpp/test/JSONProtoTest.cpp index 082c8a28b75..fd5a8d11b98 100644 --- a/lib/cpp/test/JSONProtoTest.cpp +++ b/lib/cpp/test/JSONProtoTest.cpp @@ -48,6 +48,7 @@ void testCaseSetup_1() { ooe->some_characters = "JSON THIS! \"\1"; ooe->zomg_unicode = "\xd7\n\a\t"; ooe->base64 = "\1\2\3\255"; + ooe->rfc4122_uuid = apache::thrift::TUuid{"00000000-0000-0000-0000-000000000000"}; } BOOST_AUTO_TEST_CASE(test_json_proto_1) { @@ -59,7 +60,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_1) { "535897931},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001\"},\"9\":{\"str\":\"\xd7\\" "n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":\"AQIDrQ\"},\"12\":{\"lst\"" ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64" - "\",3,1,2,3]}}"); + "\",3,1,2,3]},\"15\":{\"uid\":\"00000000-0000-0000-0000-000000000000\"},\"16\"" + ":{\"lst\":[\"uid\",0]}}"); const std::string result(apache::thrift::ThriftJSONString(*ooe)); @@ -84,6 +86,11 @@ void testCaseSetup_2() { "\xb0\xcf\x81\xe2\x84\x8e\x20\xce\x91\x74\x74" "\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80" "\xbc"; + n->my_ooe.rfc4122_uuid = apache::thrift::TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + std::vector uuiid_list; + uuiid_list.push_back(apache::thrift::TUuid{"{fa1af5ec-fdc2-4355-844a-9f0dbfd00e50}"}); + uuiid_list.push_back(apache::thrift::TUuid{"{1beece83-34f4-4fa3-b757-1ad1ac157fe3}"}); + n->my_ooe.rfc4122_uuid_list = uuiid_list; n->my_bonk.type = 31337; n->my_bonk.message = "I am a bonk... xor!"; } @@ -98,7 +105,9 @@ BOOST_AUTO_TEST_CASE(test_json_proto_2) { "1.6180339887498949},\"8\":{\"str\":\":R (me going \\\"rrrr\\\")\"},\"9\":{" "\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{\"str\":\"" "AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2" - ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}}}" + ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"5e2ab188-1726-" + "4e75-a04f-1ed9a6a89c4c\"},\"16\":{\"lst\":[\"uid\",2,\"fa1af5ec-fdc2-4355-" + "844a-9f0dbfd00e50\",\"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"]}}}}" ); const std::string result(apache::thrift::ThriftJSONString(*n)); @@ -162,12 +171,15 @@ BOOST_AUTO_TEST_CASE(test_json_proto_3) { "},\"7\":{\"dbl\":3.1415926535897931},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001" "\"},\"9\":{\"str\":\"\xd7\\n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":" "\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2" - ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}},{\"1\":{\"tf\":1},\"2\":{\"tf\":0}," + ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"00000000-0000-0000" + "-0000-000000000000\"},\"16\":{\"lst\":[\"uid\",0]}},{\"1\":{\"tf\":1},\"2\":{\"tf\":0}," "\"3\":{\"i8\":51},\"4\":{\"i16\":16},\"5\":{\"i32\":32},\"6\":{\"i64\":64}," "\"7\":{\"dbl\":1.6180339887498949},\"8\":{\"str\":\":R (me going \\\"rrrr\\\"" ")\"},\"9\":{\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{" "\"str\":\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16" - "\",3,1,2,3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}]},\"2\":{\"set\":[\"lst\",3" + "\",3,1,2,3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"5e2ab188-" + "1726-4e75-a04f-1ed9a6a89c4c\"},\"16\":{\"lst\":[\"uid\",2,\"fa1af5ec-fdc2-4355-" + "844a-9f0dbfd00e50\",\"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"]}}]},\"2\":{\"set\":[\"lst\",3" ",[\"str\",0],[\"str\",2,\"and a one\",\"and a two\"],[\"str\",3,\"then a one" ", two\",\"three!\",\"FOUR!!\"]]},\"3\":{\"map\":[\"str\",\"lst\",3,{\"nothin" "g\":[\"rec\",0],\"poe\":[\"rec\",3,{\"1\":{\"i32\":3},\"2\":{\"str\":\"quoth" @@ -192,6 +204,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_4) { OneOfEach ooe2; ooe2.read(proto.get()); + BOOST_TEST_INFO("written: " << *ooe); + BOOST_TEST_INFO("read : " << ooe2); BOOST_CHECK(*ooe == ooe2); } @@ -205,6 +219,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_5) { HolyMoley hm2; hm2.read(proto.get()); + BOOST_TEST_INFO("written: " << *hm); + BOOST_TEST_INFO("read : " << hm2); BOOST_CHECK(*hm == hm2); hm2.big[0].a_bite = 0x00; @@ -230,14 +246,14 @@ BOOST_AUTO_TEST_CASE(test_json_proto_6) { ); std::shared_ptr buffer(new TMemoryBuffer()); - std::shared_ptr proto(new TJSONProtocol(buffer)); + std::shared_ptr proto(new TJSONProtocol(buffer)); dub.write(proto.get()); Doubles dub_1; dub_1.read(proto.get()); const std::string result(apache::thrift::ThriftJSONString(dub)); const std::string result_1(apache::thrift::ThriftJSONString(dub_1)); - + BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); BOOST_CHECK_MESSAGE(!expected_result.compare(result_1), @@ -350,3 +366,39 @@ BOOST_AUTO_TEST_CASE(test_json_unicode_escaped_missing_hi_surrogate) { BOOST_CHECK_THROW(ooe2.read(proto.get()), apache::thrift::protocol::TProtocolException); } + +BOOST_AUTO_TEST_CASE(test_json_invalid_byte_range) { + // Test case for byte values outside valid range + const char json_string[] = "\"3\":{\"i8\":849}"; + + std::shared_ptr buffer(new TMemoryBuffer( + (uint8_t*)(json_string), sizeof(json_string))); + std::shared_ptr proto(new TJSONProtocol(buffer)); + + OneOfEach ooe2; + BOOST_CHECK_THROW(ooe2.read(proto.get()), + apache::thrift::protocol::TProtocolException); +} + +BOOST_AUTO_TEST_CASE(test_json_base64_padding_validation) { + auto test_base64_padding = [](const std::string& base64_value) { + std::string json_string = "{\"11\":{\"str\":\"" + base64_value + "\"}}"; + std::shared_ptr buffer(new TMemoryBuffer( + (uint8_t*)(json_string.c_str()), static_cast(json_string.size()))); + std::shared_ptr proto(new TJSONProtocol(buffer)); + + OneOfEach ooe; + BOOST_CHECK_NO_THROW(ooe.read(proto.get())); + }; + + // Valid base64 with 1 padding character + test_base64_padding("QWE="); + // Valid base64 with 2 padding characters + test_base64_padding("QQ=="); + // Just padding + test_base64_padding("="); + test_base64_padding("=="); + // Malformed base64 with excessive padding (processed conservatively) + test_base64_padding("==="); + test_base64_padding("===="); +} diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am index cd401c0f396..7c4153b49e4 100644 --- a/lib/cpp/test/Makefile.am +++ b/lib/cpp/test/Makefile.am @@ -18,18 +18,22 @@ # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc +SUBDIRS = . +SUBDIRS += fuzz + BUILT_SOURCES = gen-cpp/AnnotationTest_types.h \ gen-cpp/DebugProtoTest_types.h \ gen-cpp/EnumTest_types.h \ gen-cpp/OptionalRequiredTest_types.h \ gen-cpp/Recursive_types.h \ gen-cpp/ThriftTest_types.h \ + gen-cpp/Thrift5272_types.h \ gen-cpp/TypedefTest_types.h \ gen-cpp/ChildService.h \ gen-cpp/EmptyService.h \ gen-cpp/ParentService.h \ - gen-cpp/OneWayTest_types.h \ - gen-cpp/OneWayService.h \ + gen-cpp/OneWayTest_types.h \ + gen-cpp/OneWayService.h \ gen-cpp/proc_types.h noinst_LTLIBRARIES = libtestgencpp.la libprocessortest.la @@ -50,6 +54,8 @@ nodist_libtestgencpp_la_SOURCES = \ gen-cpp/ThriftTest_types.h \ gen-cpp/ThriftTest_constants.cpp \ gen-cpp/ThriftTest_constants.h \ + gen-cpp/Thrift5272_types.cpp \ + gen-cpp/Thrift5272_types.h \ gen-cpp/TypedefTest_types.cpp \ gen-cpp/TypedefTest_types.h \ gen-cpp/OneWayService.cpp \ @@ -83,6 +89,8 @@ Benchmark_LDADD = libtestgencpp.la check_PROGRAMS = \ UnitTests \ + UnitTestsUuid \ + UnitTestsUuidNoDirective \ TFDTransportTest \ TPipedTransportTest \ DebugProtoTest \ @@ -102,7 +110,7 @@ check_PROGRAMS = \ OpenSSLManualInitTest \ EnumTest \ RenderedDoubleConstantsTest \ - AnnotationTest + AnnotationTest if AMX_HAVE_LIBEVENT noinst_PROGRAMS += \ @@ -131,7 +139,9 @@ UnitTests_SOURCES = \ TServerSocketTest.cpp \ TServerTransportTest.cpp \ TTransportCheckThrow.h \ - ThrifttReadCheckTests.cpp + ThrifttReadCheckTests.cpp \ + Thrift5272.cpp \ + TUuidTest.cpp UnitTests_LDADD = \ libtestgencpp.la \ @@ -139,6 +149,30 @@ UnitTests_LDADD = \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) +UnitTestsUuid_SOURCES = \ + UnitTestMain.cpp \ + TUuidTestBoost.cpp + +UnitTestsUuid_LDADD = \ + libtestgencpp.la \ + $(BOOST_TEST_LDADD) \ + $(BOOST_SYSTEM_LDADD) \ + $(BOOST_THREAD_LDADD) + +UnitTestsUuid_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DTHRIFT_TUUID_SUPPORT_BOOST_UUID + +UnitTestsUuidNoDirective_SOURCES = \ + UnitTestMain.cpp \ + TUuidTestBoostNoDirective.cpp + +UnitTestsUuidNoDirective_LDADD = \ + libtestgencpp.la \ + $(BOOST_TEST_LDADD) \ + $(BOOST_SYSTEM_LDADD) \ + $(BOOST_THREAD_LDADD) + TInterruptTest_SOURCES = \ TSocketInterruptTest.cpp \ TSSLSocketInterruptTest.cpp @@ -382,17 +416,18 @@ OpenSSLManualInitTest_LDADD = \ # # Common thrift code generation rules # +# files from /test +# gen-cpp/AnnotationTest_constants.cpp gen-cpp/AnnotationTest_constants.h gen-cpp/AnnotationTest_types.cpp gen-cpp/AnnotationTest_types.h: $(top_srcdir)/test/AnnotationTest.thrift $(THRIFT) --gen cpp $< -gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/v0.16/DebugProtoTest.thrift +gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/DebugProtoTest.thrift $(THRIFT) --gen cpp $< gen-cpp/DoubleConstantsTest_constants.cpp gen-cpp/DoubleConstantsTest_constants.h: $(top_srcdir)/test/DoubleConstantsTest.thrift $(THRIFT) --gen cpp $< - gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h: $(top_srcdir)/test/EnumTest.thrift $(THRIFT) --gen cpp $< @@ -408,12 +443,17 @@ gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h: $(top_srcdir)/test/Recurs gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT) --gen cpp $< -gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h: $(top_srcdir)/test/v0.16/ThriftTest.thrift +gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen cpp $< +# files from /lib/cpp/test + gen-cpp/OneWayService.cpp gen-cpp/OneWayTest_types.h gen-cpp/OneWayService.h: OneWayTest.thrift $(THRIFT) --gen cpp $< +gen-cpp/Thrift5272_types.cpp gen-cpp/Thrift5272_types.h: Thrift5272.thrift + $(THRIFT) --gen cpp $< + gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h: processor/proc.thrift $(THRIFT) --gen cpp:templates,cob_style $< @@ -424,6 +464,9 @@ AM_CXXFLAGS = -Wall -Wextra -pedantic clean-local: $(RM) gen-cpp/* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ concurrency \ processor \ @@ -431,4 +474,6 @@ EXTRA_DIST = \ CMakeLists.txt \ DebugProtoTest_extras.cpp \ ThriftTest_extras.cpp \ - OneWayTest.thrift + OneWayTest.thrift \ + Thrift5272.thrift + diff --git a/lib/cpp/test/OneWayHTTPTest.cpp b/lib/cpp/test/OneWayHTTPTest.cpp index 7823482f1f1..8789c2c8ffb 100644 --- a/lib/cpp/test/OneWayHTTPTest.cpp +++ b/lib/cpp/test/OneWayHTTPTest.cpp @@ -55,9 +55,6 @@ using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransportException; using std::shared_ptr; -using std::cout; -using std::cerr; -using std::endl; using std::string; namespace utf = boost::unit_test; @@ -70,12 +67,12 @@ class OneWayServiceHandler : public onewaytest::OneWayServiceIf { void roundTripRPC() override { #ifdef ENABLE_STDERR_LOGGING - cerr << "roundTripRPC()" << endl; + cerr << "roundTripRPC()" << '\n'; #endif } void oneWayRPC() override { #ifdef ENABLE_STDERR_LOGGING - cerr << "oneWayRPC()" << std::endl ; + cerr << "oneWayRPC()" << '\n'; #endif } }; @@ -201,7 +198,7 @@ BOOST_AUTO_TEST_CASE( JSON_BufferedHTTP ) int port = ss->getPort() ; #ifdef ENABLE_STDERR_LOGGING - cerr << "port " << port << endl ; + cerr << "port " << port << '\n'; #endif { diff --git a/lib/cpp/test/SecurityFromBufferTest.cpp b/lib/cpp/test/SecurityFromBufferTest.cpp index 65ec8b6a26a..32f2378d38b 100644 --- a/lib/cpp/test/SecurityFromBufferTest.cpp +++ b/lib/cpp/test/SecurityFromBufferTest.cpp @@ -109,7 +109,13 @@ struct SecurityFromBufferFixture { shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); - pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #else + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #endif pServerSocketFactory->loadCertificateFromBuffer(certString("server.crt").c_str()); pServerSocketFactory->loadPrivateKeyFromBuffer(certString("server.key").c_str()); pServerSocketFactory->server(true); @@ -155,6 +161,11 @@ struct SecurityFromBufferFixture { try { pClientSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); pClientSocketFactory->authenticate(true); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pClientSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #endif pClientSocketFactory->loadCertificateFromBuffer(certString("client.crt").c_str()); pClientSocketFactory->loadPrivateKeyFromBuffer(certString("client.key").c_str()); pClientSocketFactory->loadTrustedCertificatesFromBuffer(certString("CA.pem").c_str()); @@ -199,16 +210,15 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) { try { // matrix of connection success between client and server with different SSLProtocol selections static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols"); - bool ossl1 = (OPENSSL_VERSION_NUMBER < 0x30000000L); bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] = { // server = SSLTLS SSLv2 SSLv3 TLSv1_0 TLSv1_1 TLSv1_2 // client - /* SSLTLS */ { true, false, false, ossl1, ossl1, true }, + /* SSLTLS */ { true, false, false, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, false }, - /* TLSv1_0 */ { ossl1, false, false, ossl1, false, false }, - /* TLSv1_1 */ { ossl1, false, false, false, ossl1, false }, + /* TLSv1_0 */ { true, false, false, true, false, false }, + /* TLSv1_1 */ { true, false, false, false, true, false }, /* TLSv1_2 */ { true, false, false, false, false, true } }; diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp index 06ee8fe57aa..cc71f04793d 100644 --- a/lib/cpp/test/SecurityTest.cpp +++ b/lib/cpp/test/SecurityTest.cpp @@ -108,7 +108,13 @@ struct SecurityFixture shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); - pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0:@STRENGTH"); + #else + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #endif pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str()); pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str()); pServerSocketFactory->server(true); @@ -162,6 +168,11 @@ struct SecurityFixture { pClientSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); pClientSocketFactory->authenticate(true); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pClientSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #endif pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str()); pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str()); pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str()); @@ -221,16 +232,15 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) { // matrix of connection success between client and server with different SSLProtocol selections static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols"); - bool ossl1 = (OPENSSL_VERSION_NUMBER < 0x30000000L); bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] = { // server = SSLTLS SSLv2 SSLv3 TLSv1_0 TLSv1_1 TLSv1_2 // client - /* SSLTLS */ { true, false, false, ossl1, ossl1, true }, + /* SSLTLS */ { true, false, false, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, false }, - /* TLSv1_0 */ { ossl1, false, false, ossl1, false, false }, - /* TLSv1_1 */ { ossl1, false, false, false, ossl1, false }, + /* TLSv1_0 */ { true, false, false, true, false, false }, + /* TLSv1_1 */ { true, false, false, false, true, false }, /* TLSv1_2 */ { true, false, false, false, false, true } }; diff --git a/lib/cpp/test/SpecializationTest.cpp b/lib/cpp/test/SpecializationTest.cpp index 008837d319c..7256c202998 100644 --- a/lib/cpp/test/SpecializationTest.cpp +++ b/lib/cpp/test/SpecializationTest.cpp @@ -26,6 +26,7 @@ BOOST_AUTO_TEST_CASE(test_specialization_1) { ooe.some_characters = "JSON THIS! \"\1"; ooe.zomg_unicode = "\xd7\n\a\t"; ooe.base64 = "\1\2\3\255"; + ooe.rfc4122_uuid = apache::thrift::TUuid{"00000000-0000-0000-0000-000000000000"}; Nesting n; n.my_ooe = ooe; @@ -89,6 +90,8 @@ BOOST_AUTO_TEST_CASE(test_specialization_1) { OneOfEach ooe2; ooe2.read(proto.get()); + BOOST_TEST_INFO("Write: " << ooe); + BOOST_TEST_INFO("Read : " << ooe2); BOOST_CHECK(ooe == ooe2); hm.write(proto.get()); diff --git a/lib/cpp/test/TMemoryBufferTest.cpp b/lib/cpp/test/TMemoryBufferTest.cpp index 2f1aea69411..53e5d15e010 100644 --- a/lib/cpp/test/TMemoryBufferTest.cpp +++ b/lib/cpp/test/TMemoryBufferTest.cpp @@ -36,8 +36,6 @@ using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TTransportException; using std::shared_ptr; -using std::cout; -using std::endl; using std::string; BOOST_AUTO_TEST_CASE(test_read_write_grow) { diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp index 929defa0a89..0860242bc25 100644 --- a/lib/cpp/test/TServerSocketTest.cpp +++ b/lib/cpp/test/TServerSocketTest.cpp @@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(test_bind_to_address) { accepted->close(); sock1.close(); - std::cout << "An error message from getaddrinfo on the console is expected:" << std::endl; + std::cout << "An error message from getaddrinfo on the console is expected:" << '\n'; TServerSocket sock2("257.258.259.260", 0); BOOST_CHECK_THROW(sock2.listen(), TTransportException); sock2.close(); diff --git a/lib/cpp/test/TUuidTest.cpp b/lib/cpp/test/TUuidTest.cpp new file mode 100644 index 00000000000..d2a661581c6 --- /dev/null +++ b/lib/cpp/test/TUuidTest.cpp @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +#include +#include +#include +#include + +#include + +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidTest) + +BOOST_AUTO_TEST_CASE(construction) { + BOOST_TEST(TUuid().is_nil()); +} + +BOOST_AUTO_TEST_CASE(construction_string_valid) { + const std::string expected_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + + BOOST_TEST(to_string(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")) == expected_1); + BOOST_TEST(to_string(TUuid("{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}")) == expected_1); + BOOST_TEST(to_string(TUuid("{5e2ab18817264e75a04f1ed9a6a89c4c}")) == expected_1); + BOOST_TEST(to_string(TUuid("5e2ab18817264e75a04f1ed9a6a89c4c")) == expected_1); +} + +BOOST_AUTO_TEST_CASE(construction_string_invalid) { + // This test also ensures that the constructor does not throw + const std::string expected{"00000000-0000-0000-0000-000000000000"}; + + BOOST_TEST(to_string(TUuid("5e2ab188-1726-4e75-a04f")) == expected); + BOOST_TEST(to_string(TUuid("{}")) == expected); + BOOST_TEST(to_string(TUuid("{5e2ab18817264e75a04f1ed9a6a89c4c")) == expected); + BOOST_TEST(to_string(TUuid("5e2ab18817264e75a04f1ed9a689c4c")) == expected); +} + +BOOST_AUTO_TEST_CASE(compare) { + BOOST_TEST(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c") + == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c") + != TUuid("00000000-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(TUuid("{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}") + == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + + // This comparison is expected to fail if strcmp is used + TUuid uuid_1{}; + TUuid uuid_2{}; + uuid_2.data()[15] = 0x64; + BOOST_TEST(uuid_1 != uuid_2); +} + +BOOST_AUTO_TEST_CASE(assign_valid) { + TUuid uuid_1{}; + BOOST_TEST(uuid_1.is_nil()); + uuid_1 = TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(!uuid_1.is_nil()); + + BOOST_TEST(uuid_1 == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + + uuid_1 = TUuid{"{12345678-1726-4e75-a04f-1ed9a6a89c4c}"}; + BOOST_TEST(uuid_1 != TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(uuid_1 == TUuid("{12345678-1726-4e75-a04f-1ed9a6a89c4c}")); +} + +BOOST_AUTO_TEST_CASE(assign_invalid) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(!uuid_1.is_nil()); + + BOOST_CHECK_NO_THROW(uuid_1 = TUuid{"123"}); + BOOST_TEST(uuid_1.is_nil()); + BOOST_TEST(to_string(uuid_1) == std::string{"00000000-0000-0000-0000-000000000000"}); +} + +BOOST_AUTO_TEST_CASE(swap) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + TUuid uuid_2{}; + BOOST_TEST(!uuid_1.is_nil()); + BOOST_TEST(uuid_2.is_nil()); + + using std::swap; + swap(uuid_1, uuid_2); + + BOOST_TEST(uuid_1.is_nil()); + BOOST_TEST(!uuid_2.is_nil()); + + BOOST_TEST(to_string(uuid_1) == std::string{"00000000-0000-0000-0000-000000000000"}); + BOOST_TEST(to_string(uuid_2) == std::string{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}); +} + +BOOST_AUTO_TEST_CASE(begin_end) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(std::distance(std::begin(uuid_1), std::end(uuid_1)) == uuid_1.size()); +} + +BOOST_AUTO_TEST_CASE(into_boost_uuid) { + TUuid uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + boost::uuids::uuid boost_uuid{}; + BOOST_TEST(boost_uuid.is_nil()); + std::copy(std::begin(uuid), std::end(uuid), boost_uuid.begin()); + BOOST_TEST(!boost_uuid.is_nil()); + BOOST_TEST(boost::uuids::to_string(boost_uuid) == "5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"); + BOOST_TEST(boost::uuids::to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid = gen("1f610073-db33-4d21-adf2-75460d4955cc"); + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid; + BOOST_TEST(uuid.is_nil()); + + std::copy(std::begin(boost_uuid), std::end(boost_uuid), uuid.begin()); + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_CASE(test_byte_order_variant) { + TUuid uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + boost::uuids::uuid boost_uuid{}; + BOOST_TEST(boost_uuid.is_nil()); + std::copy(std::begin(uuid), std::end(uuid), boost_uuid.begin()); + BOOST_TEST(!boost_uuid.is_nil()); + BOOST_TEST(boost_uuid.variant() == boost::uuids::uuid::variant_rfc_4122); +} + +BOOST_AUTO_TEST_CASE(test_byte_order_verify_network) { + const TUuid uuid{"{00112233-4455-6677-8899-aabbccddeeff}"}; + + for (uint8_t idx = 0; idx < uuid.size(); ++idx) { + const uint8_t expected = idx * 0x11; + BOOST_TEST(*(std::begin(uuid) + idx) == expected); + } + + const uint8_t test[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + + TUuid new_uuid; + std::copy(std::begin(test), std::end(test), std::begin(new_uuid)); + + BOOST_TEST(!new_uuid.is_nil()); + BOOST_TEST(to_string(new_uuid) == std::string{"00112233-4455-6677-8899-aabbccddeeff"}); + + BOOST_TEST(new_uuid == uuid); +} + +BOOST_AUTO_TEST_CASE(test_character_buffer) { + + const uint8_t test[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + + const TUuid uuid{test}; + + BOOST_TEST(to_string(uuid) == std::string{"00112233-4455-6677-8899-aabbccddeeff"}); +} + +BOOST_AUTO_TEST_CASE(test_boost_buffer) { + + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid = gen("1f610073-db33-4d21-adf2-75460d4955cc"); + BOOST_TEST(!boost_uuid.is_nil()); + + const TUuid uuid{boost_uuid.data}; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/TUuidTestBoost.cpp b/lib/cpp/test/TUuidTestBoost.cpp new file mode 100644 index 00000000000..81c35596e32 --- /dev/null +++ b/lib/cpp/test/TUuidTestBoost.cpp @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +#include +#include +#include +#include + +#include + +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidBoostTest) + +BOOST_AUTO_TEST_CASE(compiler_directive) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(true); + #else + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor directive must be set for these tests"); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_constructor) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("1f610073-db33-4d21-adf2-75460d4955cc")}; + BOOST_TEST(!boost_uuid.is_nil()); + const TUuid uuid{boost_uuid}; + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"1f610073-db33-4d21-adf2-75460d4955cc"}); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_assignment) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("5cb719a4-cd15-4476-8bcc-f1834b2527ee")}; + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid{}; + BOOST_TEST(uuid.is_nil()); + + uuid = boost_uuid; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"5cb719a4-cd15-4476-8bcc-f1834b2527ee"}); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/TUuidTestBoostNoDirective.cpp b/lib/cpp/test/TUuidTestBoostNoDirective.cpp new file mode 100644 index 00000000000..8af9c3572eb --- /dev/null +++ b/lib/cpp/test/TUuidTestBoostNoDirective.cpp @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +BOOST_AUTO_TEST_SUITE(TUuidBoostTestNoDirective) + +BOOST_AUTO_TEST_CASE(compiler_directive_not_set) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor must NOT be set for these tests"); + #else + BOOST_TEST(true); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} +BOOST_AUTO_TEST_SUITE_END() + +// This inclusion order is unconventional: This test specifcially tests that +// the THRIFT_TUUID_SUPPORT_BOOST_UUID directive can be set before including the header +// to enable boost::uuid support without causing linking or other errors with +// the compiled thrift library. + +#define THRIFT_TUUID_SUPPORT_BOOST_UUID +#define THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + +#include +#include + +#include +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidBoostTestNoDirective) + +BOOST_AUTO_TEST_CASE(compiler_directive_set) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(true); + #else + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor must now be set for these tests"); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_constructor) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("5cb719a4-cd15-4476-8bcc-f1834b2527ee")}; + BOOST_TEST(!boost_uuid.is_nil()); + const TUuid uuid{boost_uuid}; + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"5cb719a4-cd15-4476-8bcc-f1834b2527ee"}); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_assignment) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("1f610073-db33-4d21-adf2-75460d4955cc")}; + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid{}; + BOOST_TEST(uuid.is_nil()); + + uuid = TUuid{boost_uuid}; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"1f610073-db33-4d21-adf2-75460d4955cc"}); +} +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/lib/cpp/test/Thrift5272.cpp b/lib/cpp/test/Thrift5272.cpp new file mode 100644 index 00000000000..a6b23760adf --- /dev/null +++ b/lib/cpp/test/Thrift5272.cpp @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include "gen-cpp/Thrift5272_types.h" + +BOOST_AUTO_TEST_SUITE(Thrift5272Test) + +namespace utf = boost::unit_test; + +// Define this env var to enable some logging (in case you need to debug) +#undef ENABLE_STDERR_LOGGING + +using namespace thrift5272; + + +BOOST_AUTO_TEST_CASE( printTo ) +{ + std::stringstream ss; + std::string text; + Meta a = Meta(); + + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=0, i8_type=0, i16_type=0, i32_type=0, i64_type=0)"); + + ss.clear(); + ss.str(""); + a.byte_type = 50; + a.i8_type = 50; + a.i16_type = 50; + a.i32_type = 50; + a.i64_type = 50; + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=50, i8_type=50, i16_type=50, i32_type=50, i64_type=50)"); + + ss.clear(); + ss.str(""); + a.byte_type = 127; + a.i8_type = 127; + a.i16_type = 127; + a.i32_type = 127; + a.i64_type = 127; + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=127, i8_type=127, i16_type=127, i32_type=127, i64_type=127)"); +} + +BOOST_AUTO_TEST_CASE( ostream_handle_int8_to_str ) +{ + int8_t t = 65; + std::ostringstream o; + o << t; + BOOST_TEST(o.str() != "65", "ostingstream handles int8 correctly. let's drop specialization for Thrift5272 from TToString.h."); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/Thrift5272.thrift b/lib/cpp/test/Thrift5272.thrift new file mode 100644 index 00000000000..4be3b6075d0 --- /dev/null +++ b/lib/cpp/test/Thrift5272.thrift @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +namespace cpp thrift5272 + +// a minimal Thrift struct, to test Trift5272.cpp +struct Meta +{ + 1: byte byte_type, // keep using byte, even it'S just an alias for i8 (THRIFT-5153) + 2: i8 i8_type, + 3: i16 i16_type, + 4: i32 i32_type, + 5: i64 i64_type, +} diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp index eb4ca01b235..09dffe228d3 100644 --- a/lib/cpp/test/ThrifttReadCheckTests.cpp +++ b/lib/cpp/test/ThrifttReadCheckTests.cpp @@ -19,7 +19,6 @@ #define MAX_MESSAGE_SIZE 2 -#include #include #include #include @@ -55,8 +54,6 @@ using apache::thrift::transport::TTransportException; using apache::thrift::transport::TBufferedTransport; using apache::thrift::transport::TFramedTransport; using std::shared_ptr; -using std::cout; -using std::endl; using std::string; using std::memset; using namespace apache::thrift; @@ -171,30 +168,78 @@ BOOST_AUTO_TEST_CASE(test_tthriftbinaryprotocol_read_check_exception) { } BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_exception) { - std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); + // Set Max Message Size to 11 since all structs are 12B long + std::shared_ptr config (new TConfiguration(11)); std::shared_ptr transport(new TMemoryBuffer(config)); std::shared_ptr protocol(new TCompactProtocol(transport)); uint32_t val = 0; TType elemType = apache::thrift::protocol::T_STOP; TType elemType1 = apache::thrift::protocol::T_STOP; - TList list(T_I32, 8); + + // This list needs 12B + TList list(T_I32, 12); protocol->writeListBegin(list.elemType_, list.size_); protocol->writeListEnd(); BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); protocol->readListEnd(); - TSet set(T_I32, 8); + // This set needs 12B + TSet set(T_I32, 12); protocol->writeSetBegin(set.elemType_, set.size_); protocol->writeSetEnd(); BOOST_CHECK_THROW(protocol->readSetBegin(elemType, val), TTransportException); protocol->readSetEnd(); - TMap map(T_I32, T_I32, 8); + + // This map needs 12B (2x elem) + TMap map(T_I32, T_I32, 6); protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); protocol->writeMapEnd(); BOOST_CHECK_THROW(protocol->readMapBegin(elemType, elemType1, val), TTransportException); protocol->readMapEnd(); + + // This string needs 12B (1 for size + str) + string eleven = "1234567890A"; + protocol->writeString(eleven); + BOOST_CHECK_THROW(protocol->readString(eleven), TTransportException); +} + +BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_pass) { + // Set Max Message Size to 12 to check the edge case + std::shared_ptr config (new TConfiguration(12)); + std::shared_ptr transport(new TMemoryBuffer(config)); + std::shared_ptr protocol(new TCompactProtocol(transport)); + + uint32_t val = 0; + TType elemType = apache::thrift::protocol::T_STOP; + TType elemType1 = apache::thrift::protocol::T_STOP; + + // This list needs 12B + TList list(T_I32, 12); + protocol->writeListBegin(list.elemType_, list.size_); + protocol->writeListEnd(); + BOOST_CHECK_NO_THROW(protocol->readListBegin(elemType, val)); + protocol->readListEnd(); + + // This set needs 12B + TSet set(T_I32, 12); + protocol->writeSetBegin(set.elemType_, set.size_); + protocol->writeSetEnd(); + BOOST_CHECK_NO_THROW(protocol->readSetBegin(elemType, val)); + protocol->readSetEnd(); + + // This map needs 12B (2x elem) + TMap map(T_I32, T_I32, 6); + protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); + protocol->writeMapEnd(); + BOOST_CHECK_NO_THROW(protocol->readMapBegin(elemType, elemType1, val)); + protocol->readMapEnd(); + + // This string needs 12B (1 for size + str) + string eleven = "1234567890A"; + protocol->writeString(eleven); + BOOST_CHECK_NO_THROW(protocol->readString(eleven)); } BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) { diff --git a/lib/cpp/test/ToStringTest.cpp b/lib/cpp/test/ToStringTest.cpp index 736b33c0a5b..cb792df67b7 100644 --- a/lib/cpp/test/ToStringTest.cpp +++ b/lib/cpp/test/ToStringTest.cpp @@ -160,4 +160,13 @@ BOOST_AUTO_TEST_CASE(generated_nested_list_object_to_string) { "ListBonks(bonk=[Bonk(message=a, type=0), Bonk(message=b, type=0)])"); } +BOOST_AUTO_TEST_CASE(generated_uuid_to_string) { + thrift::test::CrazyNesting l; + l.uuid_field = apache::thrift::TUuid{"{4b686716-5f20-4deb-8ce0-9eaf379e8a3d}"}; + + BOOST_CHECK_EQUAL(to_string(l), + "CrazyNesting(string_field=, set_field=, list_field=[], binary_field=, " + "uuid_field=4b686716-5f20-4deb-8ce0-9eaf379e8a3d)"); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/concurrency/Tests.cpp b/lib/cpp/test/concurrency/Tests.cpp index 45054a92ad6..67de7893b5e 100644 --- a/lib/cpp/test/concurrency/Tests.cpp +++ b/lib/cpp/test/concurrency/Tests.cpp @@ -51,52 +51,52 @@ int main(int argc, char** argv) { ThreadFactoryTests threadFactoryTests; - std::cout << "ThreadFactory tests..." << std::endl; + std::cout << "ThreadFactory tests..." << '\n'; const int reapLoops = 2 * WEIGHT; const int reapCount = 100 * WEIGHT; const size_t floodLoops = 3; const size_t floodCount = 500 * WEIGHT; - std::cout << "\t\tThreadFactory reap N threads test: N = " << reapLoops << "x" << reapCount << std::endl; + std::cout << "\t\tThreadFactory reap N threads test: N = " << reapLoops << "x" << reapCount << '\n'; if (!threadFactoryTests.reapNThreads(reapLoops, reapCount)) { - std::cerr << "\t\ttThreadFactory reap N threads FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory reap N threads FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory flood N threads test: N = " << floodLoops << "x" << floodCount << std::endl; + std::cout << "\t\tThreadFactory flood N threads test: N = " << floodLoops << "x" << floodCount << '\n'; if (!threadFactoryTests.floodNTest(floodLoops, floodCount)) { - std::cerr << "\t\ttThreadFactory flood N threads FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory flood N threads FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory synchronous start test" << std::endl; + std::cout << "\t\tThreadFactory synchronous start test" << '\n'; if (!threadFactoryTests.synchStartTest()) { - std::cerr << "\t\ttThreadFactory synchronous start FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory synchronous start FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory monitor timeout test" << std::endl; + std::cout << "\t\tThreadFactory monitor timeout test" << '\n'; if (!threadFactoryTests.monitorTimeoutTest()) { - std::cerr << "\t\ttThreadFactory monitor timeout FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory monitor timeout FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("util") == 0) { - std::cout << "Util tests..." << std::endl; + std::cout << "Util tests..." << '\n'; - std::cout << "\t\tUtil minimum time" << std::endl; + std::cout << "\t\tUtil minimum time" << '\n'; int64_t time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); int64_t time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); - std::cout << "\t\t\tMinimum time: " << time01 - time00 << "ms" << std::endl; + std::cout << "\t\t\tMinimum time: " << time01 - time00 << "ms" << '\n'; time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); time01 = time00; @@ -107,54 +107,54 @@ int main(int argc, char** argv) { time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } - std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << std::endl; + std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << '\n'; } if (runAll || args[0].compare("timer-manager") == 0) { - std::cout << "TimerManager tests..." << std::endl; + std::cout << "TimerManager tests..." << '\n'; - std::cout << "\t\tTimerManager test00" << std::endl; + std::cout << "\t\tTimerManager test00" << '\n'; TimerManagerTests timerManagerTests; if (!timerManagerTests.test00()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test01" << std::endl; + std::cout << "\t\tTimerManager test01" << '\n'; if (!timerManagerTests.test01()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test02" << std::endl; + std::cout << "\t\tTimerManager test02" << '\n'; if (!timerManagerTests.test02()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test03" << std::endl; + std::cout << "\t\tTimerManager test03" << '\n'; if (!timerManagerTests.test03()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test04" << std::endl; + std::cout << "\t\tTimerManager test04" << '\n'; if (!timerManagerTests.test04()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("thread-manager") == 0) { - std::cout << "ThreadManager tests..." << std::endl; + std::cout << "ThreadManager tests..." << '\n'; { size_t workerCount = 10 * WEIGHT; @@ -163,26 +163,26 @@ int main(int argc, char** argv) { ThreadManagerTests threadManagerTests; - std::cout << "\t\tThreadManager api test:" << std::endl; + std::cout << "\t\tThreadManager api test:" << '\n'; if (!threadManagerTests.apiTest()) { - std::cerr << "\t\tThreadManager apiTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager apiTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager load test: worker count: " << workerCount - << " task count: " << taskCount << " delay: " << delay << std::endl; + << " task count: " << taskCount << " delay: " << delay << '\n'; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { - std::cerr << "\t\tThreadManager loadTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager block test: worker count: " << workerCount - << " delay: " << delay << std::endl; + << " delay: " << delay << '\n'; if (!threadManagerTests.blockTest(delay, workerCount)) { - std::cerr << "\t\tThreadManager blockTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager blockTest FAILED" << '\n'; return 1; } } @@ -190,7 +190,7 @@ int main(int argc, char** argv) { if (runAll || args[0].compare("thread-manager-benchmark") == 0) { - std::cout << "ThreadManager benchmark tests..." << std::endl; + std::cout << "ThreadManager benchmark tests..." << '\n'; { @@ -207,19 +207,19 @@ int main(int argc, char** argv) { size_t taskCount = workerCount * tasksPerWorker; std::cout << "\t\tThreadManager load test: worker count: " << workerCount - << " task count: " << taskCount << " delay: " << delay << std::endl; + << " task count: " << taskCount << " delay: " << delay << '\n'; ThreadManagerTests threadManagerTests; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { - std::cerr << "\t\tThreadManager loadTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } } } } - std::cout << "ALL TESTS PASSED" << std::endl; + std::cout << "ALL TESTS PASSED" << '\n'; return 0; } diff --git a/lib/cpp/test/concurrency/ThreadFactoryTests.h b/lib/cpp/test/concurrency/ThreadFactoryTests.h index 23e46e3de21..a2d55febae1 100644 --- a/lib/cpp/test/concurrency/ThreadFactoryTests.h +++ b/lib/cpp/test/concurrency/ThreadFactoryTests.h @@ -53,7 +53,7 @@ class ThreadFactoryTests { void run() override { Synchronized s(_monitor); - + if (--_count == 0) { _monitor.notify(); } @@ -82,7 +82,7 @@ class ThreadFactoryTests { threadFactory.newThread(shared_ptr(new ReapNTask(*monitor, activeCount)))); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to create " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; throw; } } @@ -96,7 +96,7 @@ class ThreadFactoryTests { (*thread)->start(); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; throw; } } @@ -107,11 +107,11 @@ class ThreadFactoryTests { monitor->wait(1000); } } - - std::cout << "\t\t\treaped " << lix* count << " threads" << std::endl; + + std::cout << "\t\t\treaped " << lix* count << " threads" << '\n'; } - std::cout << "\t\t\tSuccess!" << std::endl; + std::cout << "\t\t\tSuccess!" << '\n'; return true; } @@ -202,7 +202,7 @@ class ThreadFactoryTests { bool success = true; - std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "!" << std::endl; + std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "!" << '\n'; return true; } @@ -239,7 +239,7 @@ class ThreadFactoryTests { std::cout << "\t\t\t" << (success ? "Success" : "Failure") << ": minimum required time to elapse " << count * timeout << "ms; actual elapsed time " << endTime - startTime << "ms" - << std::endl; + << '\n'; return success; } @@ -250,14 +250,14 @@ class ThreadFactoryTests { ~FloodTask() override { if (_id % 10000 == 0) { Synchronized sync(_mon); - std::cout << "\t\tthread " << _id << " done" << std::endl; + std::cout << "\t\tthread " << _id << " done" << '\n'; } } void run() override { if (_id % 10000 == 0) { Synchronized sync(_mon); - std::cout << "\t\tthread " << _id << " started" << std::endl; + std::cout << "\t\tthread " << _id << " started" << '\n'; } } const size_t _id; @@ -270,7 +270,7 @@ class ThreadFactoryTests { bool success = false; Monitor mon; - + for (size_t lix = 0; lix < loop; lix++) { ThreadFactory threadFactory = ThreadFactory(); @@ -287,14 +287,14 @@ class ThreadFactoryTests { } catch (TException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; return success; } } Synchronized sync(mon); - std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << std::endl; + std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << '\n'; success = true; } diff --git a/lib/cpp/test/concurrency/ThreadManagerTests.h b/lib/cpp/test/concurrency/ThreadManagerTests.h index fee7c7c51a1..d0494ec5d16 100644 --- a/lib/cpp/test/concurrency/ThreadManagerTests.h +++ b/lib/cpp/test/concurrency/ThreadManagerTests.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace apache { namespace thrift { @@ -42,16 +44,7 @@ static void expiredNotifier(std::shared_ptr runnable) } static void sleep_(int64_t millisec) { - Monitor _sleep; - Synchronized s(_sleep); - - try { - _sleep.wait(millisec); - } catch (TimedOutException&) { - ; - } catch (...) { - assert(0); - } + std::this_thread::sleep_for(std::chrono::milliseconds(millisec)); } class ThreadManagerTests { @@ -76,7 +69,7 @@ class ThreadManagerTests { { Synchronized s(_monitor); - // std::cout << "Thread " << _count << " completed " << std::endl; + // std::cout << "Thread " << _count << " completed " << '\n'; _count--; if (_count % 10000 == 0) { @@ -131,13 +124,13 @@ class ThreadManagerTests { threadManager->add(*ix); } - std::cout << "\t\t\t\tloaded " << count << " tasks to execute" << std::endl; + std::cout << "\t\t\t\tloaded " << count << " tasks to execute" << '\n'; { Synchronized s(monitor); while (activeCount > 0) { - std::cout << "\t\t\t\tactiveCount = " << activeCount << std::endl; + std::cout << "\t\t\t\tactiveCount = " << activeCount << '\n'; monitor.wait(); } } @@ -184,13 +177,13 @@ class ThreadManagerTests { std::cout << "\t\t\tfirst start: " << firstTime << " Last end: " << lastTime << " min: " << minTime << "ms max: " << maxTime << "ms average: " << averageTime - << "ms" << std::endl; + << "ms" << '\n'; bool success = (time01 - time00) >= ((int64_t)count * timeout) / (int64_t)workerCount; std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "! expected time: " << ((int64_t)count * timeout) / (int64_t)workerCount << "ms elapsed time: " << time01 - time00 - << "ms" << std::endl; + << "ms" << '\n'; return success; } @@ -307,7 +300,7 @@ class ThreadManagerTests { } std::cout << "\t\t\t" - << "Pending tasks " << threadManager->pendingTaskCount() << std::endl; + << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; { Synchronized s(blockMonitor); @@ -323,18 +316,18 @@ class ThreadManagerTests { } std::cout << "\t\t\t" - << "Pending tasks " << threadManager->pendingTaskCount() << std::endl; + << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; try { threadManager->add(extraTask, 1); } catch (TimedOutException&) { std::cout << "\t\t\t" - << "add timed out unexpectedly" << std::endl; + << "add timed out unexpectedly" << '\n'; throw TException("Unexpected timeout adding task"); } catch (TooManyPendingTasksException&) { std::cout << "\t\t\t" - << "add encountered too many pending exepctions" << std::endl; + << "add encountered too many pending exepctions" << '\n'; throw TException("Unexpected timeout adding task"); } @@ -375,10 +368,10 @@ class ThreadManagerTests { } } catch (TException& e) { - std::cout << "ERROR: " << e.what() << std::endl; + std::cout << "ERROR: " << e.what() << '\n'; } - std::cout << "\t\t\t" << (success ? "Success" : "Failure") << std::endl; + std::cout << "\t\t\t" << (success ? "Success" : "Failure") << '\n'; return success; } @@ -390,7 +383,7 @@ class ThreadManagerTests { sleep_(100); int64_t b = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); if (b - a < 50 || b - a > 150) { - std::cerr << "\t\t\texpected 100ms gap, found " << (b-a) << "ms gap instead." << std::endl; + std::cerr << "\t\t\texpected 100ms gap, found " << (b-a) << "ms gap instead." << '\n'; return false; } @@ -403,18 +396,18 @@ class ThreadManagerTests { shared_ptr threadManager = ThreadManager::newSimpleThreadManager(1); threadManager->threadFactory(threadFactory); - std::cout << "\t\t\t\tstarting.. " << std::endl; + std::cout << "\t\t\t\tstarting.. " << '\n'; threadManager->start(); threadManager->setExpireCallback(expiredNotifier); // std::bind(&ThreadManagerTests::expiredNotifier, this)); -#define EXPECT(FUNC, COUNT) { size_t c = FUNC; if (c != COUNT) { std::cerr << "expected " #FUNC" to be " #COUNT ", but was " << c << std::endl; return false; } } +#define EXPECT(FUNC, COUNT) { size_t c = FUNC; if (c != COUNT) { std::cerr << "expected " #FUNC" to be " #COUNT ", but was " << c << '\n'; return false; } } EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tadd 2nd worker.. " << std::endl; + std::cout << "\t\t\t\tadd 2nd worker.. " << '\n'; threadManager->addWorker(); @@ -422,7 +415,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 2); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove 2nd worker.. " << std::endl; + std::cout << "\t\t\t\tremove 2nd worker.. " << '\n'; threadManager->removeWorker(); @@ -430,7 +423,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove 1st worker.. " << std::endl; + std::cout << "\t\t\t\tremove 1st worker.. " << '\n'; threadManager->removeWorker(); @@ -438,7 +431,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tadd blocking task.. " << std::endl; + std::cout << "\t\t\t\tadd blocking task.. " << '\n'; // We're going to throw a blocking task into the mix Monitor entryMonitor; // signaled when task is running @@ -454,7 +447,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tadd other task.. " << std::endl; + std::cout << "\t\t\t\tadd other task.. " << '\n'; shared_ptr otherTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); @@ -465,7 +458,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 2); - std::cout << "\t\t\t\tremove blocking task specifically.. " << std::endl; + std::cout << "\t\t\t\tremove blocking task specifically.. " << '\n'; threadManager->remove(blockingTask); @@ -473,11 +466,11 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tremove next pending task.." << std::endl; + std::cout << "\t\t\t\tremove next pending task.." << '\n'; shared_ptr nextTask = threadManager->removeNextPending(); if (nextTask != otherTask) { - std::cerr << "\t\t\t\t\texpected removeNextPending to return otherTask" << std::endl; + std::cerr << "\t\t\t\t\texpected removeNextPending to return otherTask" << '\n'; return false; } @@ -485,15 +478,15 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove next pending task (none left).." << std::endl; + std::cout << "\t\t\t\tremove next pending task (none left).." << '\n'; nextTask = threadManager->removeNextPending(); if (nextTask) { - std::cerr << "\t\t\t\t\texpected removeNextPending to return an empty Runnable" << std::endl; + std::cerr << "\t\t\t\t\texpected removeNextPending to return an empty Runnable" << '\n'; return false; } - std::cout << "\t\t\t\tadd 2 expired tasks and 1 not.." << std::endl; + std::cout << "\t\t\t\tadd 2 expired tasks and 1 not.." << '\n'; shared_ptr expiredTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); @@ -509,28 +502,28 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 3); EXPECT(threadManager->expiredTaskCount(), 0); - std::cout << "\t\t\t\tremove expired tasks.." << std::endl; + std::cout << "\t\t\t\tremove expired tasks.." << '\n'; if (!m_expired.empty()) { - std::cerr << "\t\t\t\t\texpected m_expired to be empty" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be empty" << '\n'; return false; } threadManager->removeExpiredTasks(); if (m_expired.size() != 2) { - std::cerr << "\t\t\t\t\texpected m_expired to be set" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be set" << '\n'; return false; } if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired[0] to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired[0] to be the expired task" << '\n'; return false; } m_expired.pop_front(); if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired[1] to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired[1] to be the expired task" << '\n'; return false; } @@ -543,23 +536,23 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 2); - std::cout << "\t\t\t\tadd expired task (again).." << std::endl; + std::cout << "\t\t\t\tadd expired task (again).." << '\n'; threadManager->add(expiredTask, 0, 1); // expires in 1ms sleep_(50); // make sure enough time elapses for it to expire - the shortest expiration time is 1ms - std::cout << "\t\t\t\tadd worker to consume expired task.." << std::endl; + std::cout << "\t\t\t\tadd worker to consume expired task.." << '\n'; threadManager->addWorker(); sleep_(100); // make sure it has time to spin up and expire the task if (m_expired.empty()) { - std::cerr << "\t\t\t\t\texpected m_expired to be set" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be set" << '\n'; return false; } if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be the expired task" << '\n'; return false; } @@ -570,16 +563,16 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); - std::cout << "\t\t\t\ttry to remove too many workers" << std::endl; + std::cout << "\t\t\t\ttry to remove too many workers" << '\n'; try { threadManager->removeWorker(2); - std::cerr << "\t\t\t\t\texpected InvalidArgumentException" << std::endl; + std::cerr << "\t\t\t\t\texpected InvalidArgumentException" << '\n'; return false; } catch (const InvalidArgumentException&) { /* expected */ } - std::cout << "\t\t\t\tremove worker.. " << std::endl; + std::cout << "\t\t\t\tremove worker.. " << '\n'; threadManager->removeWorker(); @@ -588,7 +581,7 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); - std::cout << "\t\t\t\tadd blocking task.. " << std::endl; + std::cout << "\t\t\t\tadd blocking task.. " << '\n'; threadManager->add(blockingTask); @@ -596,7 +589,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tadd worker.. " << std::endl; + std::cout << "\t\t\t\tadd worker.. " << '\n'; threadManager->addWorker(); { @@ -610,7 +603,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tunblock task and remove worker.. " << std::endl; + std::cout << "\t\t\t\tunblock task and remove worker.. " << '\n'; { Synchronized s(blockMonitor); @@ -623,7 +616,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tcleanup.. " << std::endl; + std::cout << "\t\t\t\tcleanup.. " << '\n'; blockingTask.reset(); threadManager.reset(); diff --git a/lib/cpp/test/concurrency/TimerManagerTests.h b/lib/cpp/test/concurrency/TimerManagerTests.h index 2d1a2620ab5..9a532320019 100644 --- a/lib/cpp/test/concurrency/TimerManagerTests.h +++ b/lib/cpp/test/concurrency/TimerManagerTests.h @@ -46,7 +46,7 @@ class TimerManagerTests { _success(false), _done(false) {} - ~Task() override { std::cerr << this << std::endl; } + ~Task() override { std::cerr << this << '\n'; } void run() override { @@ -84,7 +84,7 @@ class TimerManagerTests { timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); if (timerManager.state() != TimerManager::STARTED) { - std::cerr << "timerManager is not in the STARTED state, but should be" << std::endl; + std::cerr << "timerManager is not in the STARTED state, but should be" << '\n'; return false; } @@ -104,15 +104,15 @@ class TimerManagerTests { } if (!task->_done) { - std::cerr << "task is not done, but it should have executed" << std::endl; + std::cerr << "task is not done, but it should have executed" << '\n'; return false; } - std::cout << "\t\t\t" << (task->_success ? "Success" : "Failure") << "!" << std::endl; + std::cout << "\t\t\t" << (task->_success ? "Success" : "Failure") << "!" << '\n'; } if (orphanTask->_done) { - std::cerr << "orphan task is done, but it should not have executed" << std::endl; + std::cerr << "orphan task is done, but it should not have executed" << '\n'; return false; } diff --git a/lib/cpp/test/fuzz/CMakeLists.txt b/lib/cpp/test/fuzz/CMakeLists.txt new file mode 100644 index 00000000000..67d9ef7fb35 --- /dev/null +++ b/lib/cpp/test/fuzz/CMakeLists.txt @@ -0,0 +1,157 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Fuzz testing configuration + +# Generate FuzzTest code +add_custom_command(OUTPUT gen-cpp/FuzzTest_types.cpp + gen-cpp/FuzzTest_types.h + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/FuzzTest.thrift +) + +# Create a library for the generated code +add_library(fuzztest_gen + gen-cpp/FuzzTest_types.cpp +=) +target_link_libraries(fuzztest_gen thrift) + +# Common fuzzing header +set(FUZZ_COMMON_HEADERS + FuzzCommon.tcc +) + +# Add fuzzing flags when using Clang +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(FUZZING_FLAGS "-fsanitize=fuzzer,address -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FUZZING_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FUZZING_FLAGS}") +endif() + +# Compact protocol fuzzer +add_executable(FuzzParseCompact + FuzzParseCompact.cpp + ${FUZZ_COMMON_HEADERS} +) + +target_link_libraries(FuzzParseCompact + thrift + fuzztest_gen +) + +# Compact protocol roundtrip fuzzer +add_executable(FuzzRoundtripCompact + FuzzRoundtripCompact.cpp +) + +target_link_libraries(FuzzRoundtripCompact + thrift + fuzztest_gen +) + +# Binary protocol fuzzer +add_executable(FuzzParseBinary + FuzzParseBinary.cpp + ${FUZZ_COMMON_HEADERS} +) + +target_link_libraries(FuzzParseBinary + thrift + fuzztest_gen +) + +# Binary protocol roundtrip fuzzer +add_executable(FuzzRoundtripBinary + FuzzRoundtripBinary.cpp +) + +target_link_libraries(FuzzRoundtripBinary + thrift + fuzztest_gen +) + +# JSON protocol fuzzer +add_executable(FuzzParseJson + FuzzParseJson.cpp + ${FUZZ_COMMON_HEADERS} +) + +target_link_libraries(FuzzParseJson + thrift + fuzztest_gen +) + +# JSON protocol roundtrip fuzzer +add_executable(FuzzRoundtripJson + FuzzRoundtripJson.cpp + ${FUZZ_COMMON_HEADERS} +) + +target_link_libraries(FuzzRoundtripJson + thrift + fuzztest_gen +) + +# Create directories for fuzzing corpus +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip) + +# Add test targets that run the fuzzers briefly +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_test(NAME FuzzParseCompact_run + COMMAND FuzzParseCompact -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol + ) + add_test(NAME FuzzRoundtripCompact_run + COMMAND FuzzRoundtripCompact -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip + ) + add_test(NAME FuzzParseBinary_run + COMMAND FuzzParseBinary -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol + ) + add_test(NAME FuzzRoundtripBinary_run + COMMAND FuzzRoundtripBinary -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip + ) + add_test(NAME FuzzParseJson_run + COMMAND FuzzParseJson -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol + ) + add_test(NAME FuzzRoundtripJson_run + COMMAND FuzzRoundtripJson -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip + ) +else() + add_test(NAME FuzzParseCompact_run + COMMAND FuzzParseCompact ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol + ) + add_test(NAME FuzzRoundtripCompact_run + COMMAND FuzzRoundtripCompact ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip + ) + add_test(NAME FuzzParseBinary_run + COMMAND FuzzParseBinary ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol + ) + add_test(NAME FuzzRoundtripBinary_run + COMMAND FuzzRoundtripBinary ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip + ) + add_test(NAME FuzzParseJson_run + COMMAND FuzzParseJson ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol + ) + add_test(NAME FuzzRoundtripJson_run + COMMAND FuzzRoundtripJson ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip + ) +endif() \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzCommon.tcc b/lib/cpp/test/fuzz/FuzzCommon.tcc new file mode 100644 index 00000000000..da936e48c88 --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzCommon.tcc @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef THRIFT_TEST_FUZZ_COMMON_TCC_ +#define THRIFT_TEST_FUZZ_COMMON_TCC_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gen-cpp/FuzzTest_types.h" + +namespace apache { namespace thrift { namespace fuzzer { + +using namespace apache::thrift::transport; +using namespace apache::thrift::protocol; +using namespace fuzz; + +// 10MB message size limit to prevent over-allocation during fuzzing +const int FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024; + +inline bool is_nan_false_positive(FuzzTest& test1, FuzzTest& test2) { + BasicTypes& b1 = test1.basic; + BasicTypes& b2 = test2.basic; + if (std::isnan(b1.double_field) && std::isnan(b2.double_field)) { + b1.double_field = 0.0; + b2.double_field = 0.0; + } + + // Check for NaN in containers if they contain doubles + // This is a simplified version - may need adjustment based on actual schema + + return test1 == test2; +} + +// Simple parse-only fuzzer +template +int fuzz_parse(const uint8_t* data, size_t size) { + try { + std::shared_ptr config(new TConfiguration(FUZZ_MAX_MESSAGE_SIZE)); + std::shared_ptr trans(new TMemoryBuffer(const_cast(data), size, TMemoryBuffer::OBSERVE, config)); + std::shared_ptr proto(new ProtocolType(trans)); + + FuzzTest test; + test.read(proto.get()); + } catch (const TException&) { + // Ignore any Thrift exceptions - they're expected when fuzzing + } + return 0; +} + +// Roundtrip fuzzer that verifies serialization/deserialization +template +int fuzz_roundtrip(const uint8_t* data, size_t size) { + try { + std::shared_ptr config(new TConfiguration(FUZZ_MAX_MESSAGE_SIZE)); + + // First parse + std::shared_ptr trans(new TMemoryBuffer(const_cast(data), size, TMemoryBuffer::OBSERVE, config)); + std::shared_ptr proto(new ProtocolType(trans)); + + FuzzTest test1; + test1.read(proto.get()); + + // Serialize back + std::shared_ptr outTrans(new TMemoryBuffer(config)); + std::shared_ptr outProto(new ProtocolType(outTrans)); + test1.write(outProto.get()); + + // Get serialized data + std::string serialized = outTrans->getBufferAsString(); + + // Deserialize again + std::shared_ptr reTrans(new TMemoryBuffer(config)); + reTrans->write((const uint8_t*)serialized.data(), static_cast(serialized.size())); + std::shared_ptr reProto(new ProtocolType(reTrans)); + + FuzzTest test2; + test2.read(reProto.get()); + + // Verify equality + if (!(test1 == test2) && !is_nan_false_positive(test1, test2)) { + const std::string str1(apache::thrift::ThriftDebugString(test1)); + const std::string str2(apache::thrift::ThriftDebugString(test2)); + + std::cout << "Expected:\n" << str1 << "\nGotten:\n" << str2 << std::endl; + + throw std::runtime_error("Roundtrip failed"); + } + } catch (const TException&) { + // Ignore any Thrift exceptions - they're expected when fuzzing + } + return 0; +} + +}}} // apache::thrift::fuzzer + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +__attribute__((weak)) int main(int argc, char** argv) { + return 0; +} +#endif + +#endif // THRIFT_TEST_FUZZ_COMMON_TCC_ \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzParseBinary.cpp b/lib/cpp/test/fuzz/FuzzParseBinary.cpp new file mode 100644 index 00000000000..b135d9a3b9e --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzParseBinary.cpp @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_parse(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzParseCompact.cpp b/lib/cpp/test/fuzz/FuzzParseCompact.cpp new file mode 100644 index 00000000000..01e47a0db52 --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzParseCompact.cpp @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_parse(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzParseJson.cpp b/lib/cpp/test/fuzz/FuzzParseJson.cpp new file mode 100644 index 00000000000..a9bf408079f --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzParseJson.cpp @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_parse(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzRoundtripBinary.cpp b/lib/cpp/test/fuzz/FuzzRoundtripBinary.cpp new file mode 100644 index 00000000000..999bb094115 --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzRoundtripBinary.cpp @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_roundtrip(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzRoundtripCompact.cpp b/lib/cpp/test/fuzz/FuzzRoundtripCompact.cpp new file mode 100644 index 00000000000..0e07fa9e856 --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzRoundtripCompact.cpp @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_roundtrip(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/FuzzRoundtripJson.cpp b/lib/cpp/test/fuzz/FuzzRoundtripJson.cpp new file mode 100644 index 00000000000..2a11547f99a --- /dev/null +++ b/lib/cpp/test/fuzz/FuzzRoundtripJson.cpp @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "FuzzCommon.tcc" + +using namespace apache::thrift::protocol; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return apache::thrift::fuzzer::fuzz_roundtrip(data, size); +} \ No newline at end of file diff --git a/lib/cpp/test/fuzz/Makefile.am b/lib/cpp/test/fuzz/Makefile.am new file mode 100644 index 00000000000..940484db926 --- /dev/null +++ b/lib/cpp/test/fuzz/Makefile.am @@ -0,0 +1,96 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc + +# Generate FuzzTest code +BUILT_SOURCES = gen-cpp/FuzzTest_types.h + +noinst_LTLIBRARIES = libfuzztest_gen.la + +nodist_libfuzztest_gen_la_SOURCES = \ + gen-cpp/FuzzTest_types.cpp \ + gen-cpp/FuzzTest_types.h + +libfuzztest_gen_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la + +# Common fuzzing headers +noinst_HEADERS = FuzzCommon.tcc + +# Fuzzing executables +AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/src -I$(top_srcdir)/lib/cpp/src/thrift -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. + +check_PROGRAMS = FuzzParseCompact FuzzParseBinary FuzzRoundtripCompact FuzzRoundtripBinary FuzzParseJson FuzzRoundtripJson + +FuzzParseCompact_SOURCES = FuzzParseCompact.cpp FuzzCommon.tcc +FuzzParseCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzParseCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzParseCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +FuzzRoundtripCompact_SOURCES = FuzzRoundtripCompact.cpp FuzzCommon.tcc +FuzzRoundtripCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzRoundtripCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzRoundtripCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +FuzzParseBinary_SOURCES = FuzzParseBinary.cpp FuzzCommon.tcc +FuzzParseBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzParseBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzParseBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +FuzzRoundtripBinary_SOURCES = FuzzRoundtripBinary.cpp FuzzCommon.tcc +FuzzRoundtripBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzRoundtripBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzRoundtripBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +FuzzParseJson_SOURCES = FuzzParseJson.cpp FuzzCommon.tcc +FuzzParseJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzParseJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzParseJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +FuzzRoundtripJson_SOURCES = FuzzRoundtripJson.cpp FuzzCommon.tcc +FuzzRoundtripJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la +FuzzRoundtripJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g +if USING_CLANG +FuzzRoundtripJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer +endif + +# Generate thrift files +gen-cpp/FuzzTest_types.cpp gen-cpp/FuzzTest_types.h: $(top_srcdir)/test/FuzzTest.thrift + $(THRIFT) --gen cpp $< + +# Clean target +clean-local: + $(RM) -rf gen-cpp + $(RM) -f $(check_PROGRAMS) + $(RM) -f *.o *.lo *.la + $(RM) -rf .libs + +CLEANFILES = gen-cpp/* + +EXTRA_DIST = CMakeLists.txt FuzzParseCompact.cpp FuzzParseBinary.cpp FuzzRoundtripCompact.cpp FuzzRoundtripBinary.cpp FuzzParseJson.cpp FuzzRoundtripJson.cpp \ No newline at end of file diff --git a/lib/cpp/test/fuzz/README.md b/lib/cpp/test/fuzz/README.md new file mode 100644 index 00000000000..8cde0294010 --- /dev/null +++ b/lib/cpp/test/fuzz/README.md @@ -0,0 +1,23 @@ +# C++ Fuzzing README + +To build the fuzz targets, run `make check` in this directory. The build system uses LLVM's libFuzzer for fuzzing the C++ Thrift implementation. + +These are standard libFuzzer targets, so you can run them using the standard libFuzzer interface. After building, you can run a fuzzer using: +```bash +./ +``` + +We currently have six fuzz targets: + +* FuzzParseBinary -- fuzzes the deserialization of the Binary protocol +* FuzzParseCompact -- fuzzes the deserialization of the Compact protocol +* FuzzParseJson -- fuzzes the deserialization of the JSON protocol +* FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol (i.e. serializes then deserializes and compares the result) +* FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol +* FuzzRoundtripJson -- fuzzes the roundtrip of the JSON protocol + +The fuzzers use libFuzzer's built-in mutation engine to generate test cases. Each fuzzer implements the standard `LLVMFuzzerTestOneInput` interface and uses common testing code from `FuzzCommon.tcc`. + +For more information about libFuzzer and its options, see the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html). + +You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these C++ fuzzers, since the wire formats are identical between implementations. \ No newline at end of file diff --git a/lib/cpp/test/processor/ServerThread.h b/lib/cpp/test/processor/ServerThread.h index 9cca2d6002e..45c0906725e 100644 --- a/lib/cpp/test/processor/ServerThread.h +++ b/lib/cpp/test/processor/ServerThread.h @@ -91,7 +91,7 @@ class ServerThread { try { stop(); } catch (...) { - GlobalOutput.printf("error shutting down server"); + TOutput::instance().printf("error shutting down server"); } } } diff --git a/lib/d/Makefile.am b/lib/d/Makefile.am index 013721720b5..6f014c83189 100644 --- a/lib/d/Makefile.am +++ b/lib/d/Makefile.am @@ -192,6 +192,9 @@ TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \ precross: all-local $(MAKE) -C test precross +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ test \ diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d index e843a5c8549..040f0fa91ea 100644 --- a/lib/d/src/thrift/base.d +++ b/lib/d/src/thrift/base.d @@ -50,7 +50,7 @@ class TCompoundOperationException : TException { /// The Thrift version string, used for informative purposes. // Note: This is currently hardcoded, but will likely be filled in by the build // system in future versions. -enum VERSION = "0.20.0"; +enum VERSION = "0.23.0"; /** * Functions used for logging inside Thrift. diff --git a/lib/d/test/Makefile.am b/lib/d/test/Makefile.am index 44364f9d97c..28f3f3ec4a0 100644 --- a/lib/d/test/Makefile.am +++ b/lib/d/test/Makefile.am @@ -38,6 +38,8 @@ thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \ $(thrift_test_gen): $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT) --gen d $< +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am # The actual test targets. # There just must be some way to reassign a variable without warnings in diff --git a/lib/dart/Makefile.am b/lib/dart/Makefile.am index bd12a92f020..3518a87ebe8 100644 --- a/lib/dart/Makefile.am +++ b/lib/dart/Makefile.am @@ -17,6 +17,9 @@ # under the License. # +# Dart build command +DARTPUB = dart pub + all-local: $(DARTPUB) get @@ -28,6 +31,9 @@ clean-local: check-local: all +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/.pub find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r diff --git a/lib/dart/lib/src/browser/t_web_socket.dart b/lib/dart/lib/src/browser/t_web_socket.dart index 1d0bfeb449d..16678311506 100644 --- a/lib/dart/lib/src/browser/t_web_socket.dart +++ b/lib/dart/lib/src/browser/t_web_socket.dart @@ -49,19 +49,19 @@ class TWebSocket implements TSocket { : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { - if (url == null || !url.hasAuthority || !url.hasPort) { + if (!url.hasAuthority || !url.hasPort) { throw ArgumentError('Invalid url'); } } - WebSocket _socket; + WebSocket? _socket; @override - bool get isOpen => _socket != null && _socket.readyState == WebSocket.OPEN; + bool get isOpen => _socket != null && _socket!.readyState == WebSocket.OPEN; @override bool get isClosed => - _socket == null || _socket.readyState == WebSocket.CLOSED; + _socket == null ||_socket!.readyState == WebSocket.CLOSED; @override Future open() { @@ -71,19 +71,19 @@ class TWebSocket implements TSocket { } _socket = WebSocket(url.toString()); - _socket.onError.listen(_onError); - _socket.onOpen.listen(_onOpen); - _socket.onClose.listen(_onClose); - _socket.onMessage.listen(_onMessage); + _socket!.onError.listen(_onError); + _socket!.onOpen.listen(_onOpen); + _socket!.onClose.listen(_onClose); + _socket!.onMessage.listen(_onMessage); - return _socket.onOpen.first; + return _socket!.onOpen.first; } @override Future close() { if (_socket != null) { - _socket.close(); - return _socket.onClose.first; + _socket!.close(); + return _socket!.onClose.first; } else { return Future.value(); } @@ -98,7 +98,7 @@ class TWebSocket implements TSocket { void _sendRequests() { while (isOpen && _requests.isNotEmpty) { Uint8List data = _requests.removeAt(0); - _socket.sendString(base64.encode(data)); + _socket!.sendString(base64.encode(data)); } } diff --git a/lib/dart/lib/src/console/t_tcp_socket.dart b/lib/dart/lib/src/console/t_tcp_socket.dart index 610d6333cec..7c17f42ec0c 100644 --- a/lib/dart/lib/src/console/t_tcp_socket.dart +++ b/lib/dart/lib/src/console/t_tcp_socket.dart @@ -37,7 +37,7 @@ class TTcpSocket implements TSocket { @override Stream get onMessage => _onMessageController.stream; - TTcpSocket(Socket socket) + TTcpSocket(Socket? socket) : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { @@ -46,10 +46,10 @@ class TTcpSocket implements TSocket { } _socket = socket; - _socket.listen(_onMessage, onError: _onError, onDone: close); + _socket!.listen(_onMessage, onError: _onError, onDone: close); } - Socket _socket; + Socket? _socket; @override bool get isOpen => _socket != null; @@ -65,7 +65,7 @@ class TTcpSocket implements TSocket { @override Future close() async { if (_socket != null) { - await _socket.close(); + await _socket!.close(); _socket = null; } @@ -74,7 +74,9 @@ class TTcpSocket implements TSocket { @override void send(Uint8List data) { - _socket.add(data); + if (_socket != null) { + _socket!.add(data); + } } void _onMessage(List message) { diff --git a/lib/dart/lib/src/console/t_web_socket.dart b/lib/dart/lib/src/console/t_web_socket.dart index d69cafe0bf2..98fdf7005e9 100644 --- a/lib/dart/lib/src/console/t_web_socket.dart +++ b/lib/dart/lib/src/console/t_web_socket.dart @@ -38,7 +38,7 @@ class TWebSocket implements TSocket { @override Stream get onMessage => _onMessageController.stream; - TWebSocket(WebSocket socket) + TWebSocket(WebSocket? socket) : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { @@ -47,10 +47,12 @@ class TWebSocket implements TSocket { } _socket = socket; - _socket.listen(_onMessage, onError: _onError, onDone: close); + _socket!.listen((dynamic message) => _onMessage(message as String), + onError: (dynamic error) => _onError(error), + onDone: () => close(),); } - WebSocket _socket; + WebSocket? _socket; @override bool get isOpen => _socket != null; @@ -66,7 +68,7 @@ class TWebSocket implements TSocket { @override Future close() async { if (_socket != null) { - await _socket.close(); + await _socket!.close(); _socket = null; } @@ -75,7 +77,9 @@ class TWebSocket implements TSocket { @override void send(Uint8List data) { - _socket.add(base64.encode(data)); + if (_socket != null) { + _socket!.add(base64.encode(data)); + } } void _onMessage(String message) { diff --git a/lib/dart/lib/src/protocol/t_binary_protocol.dart b/lib/dart/lib/src/protocol/t_binary_protocol.dart index 9f8f3bf3364..5ddab2cc7eb 100644 --- a/lib/dart/lib/src/protocol/t_binary_protocol.dart +++ b/lib/dart/lib/src/protocol/t_binary_protocol.dart @@ -114,7 +114,6 @@ class TBinaryProtocol extends TProtocol { @override void writeBool(bool b) { - if (b == null) b = false; writeByte(b ? 1 : 0); } @@ -122,7 +121,6 @@ class TBinaryProtocol extends TProtocol { @override void writeByte(int byte) { - if (byte == null) byte = 0; _byteOut.setUint8(0, byte); transport.write(_byteOut.buffer.asUint8List(), 0, 1); } @@ -131,7 +129,6 @@ class TBinaryProtocol extends TProtocol { @override void writeI16(int i16) { - if (i16 == null) i16 = 0; _i16Out.setInt16(0, i16); transport.write(_i16Out.buffer.asUint8List(), 0, 2); } @@ -140,7 +137,6 @@ class TBinaryProtocol extends TProtocol { @override void writeI32(int i32) { - if (i32 == null) i32 = 0; _i32Out.setInt32(0, i32); transport.write(_i32Out.buffer.asUint8List(), 0, 4); } @@ -149,7 +145,6 @@ class TBinaryProtocol extends TProtocol { @override void writeI64(int i64) { - if (i64 == null) i64 = 0; var i = Int64(i64); var bts = i.toBytes(); for (var j = 0; j < 8; j++) { @@ -160,7 +155,7 @@ class TBinaryProtocol extends TProtocol { @override void writeString(String s) { - var bytes = s != null ? _utf8Codec.encode(s) : Uint8List.fromList([]); + var bytes = _utf8Codec.encode(s); writeI32(bytes.length); transport.write(bytes, 0, bytes.length); } @@ -169,7 +164,6 @@ class TBinaryProtocol extends TProtocol { @override void writeDouble(double d) { - if (d == null) d = 0.0; _doubleOut.setFloat64(0, d); transport.write(_doubleOut.buffer.asUint8List(), 0, 8); } diff --git a/lib/dart/lib/src/protocol/t_compact_protocol.dart b/lib/dart/lib/src/protocol/t_compact_protocol.dart index dc26722d393..341b659e35c 100644 --- a/lib/dart/lib/src/protocol/t_compact_protocol.dart +++ b/lib/dart/lib/src/protocol/t_compact_protocol.dart @@ -54,7 +54,8 @@ class TCompactProtocol extends TProtocol { static const int TYPE_MAP = 0x0B; static const int TYPE_STRUCT = 0x0C; - static final List _typeMap = List.unmodifiable(List(16) +static final List _typeMap = List.unmodifiable( + List.filled(16, 0) ..[TType.STOP] = TType.STOP ..[TType.BOOL] = TYPE_BOOLEAN_TRUE ..[TType.BYTE] = TYPE_BYTE @@ -66,7 +67,8 @@ class TCompactProtocol extends TProtocol { ..[TType.LIST] = TYPE_LIST ..[TType.SET] = TYPE_SET ..[TType.MAP] = TYPE_MAP - ..[TType.STRUCT] = TYPE_STRUCT); + ..[TType.STRUCT] = TYPE_STRUCT, +); static const Utf8Codec _utf8Codec = Utf8Codec(); @@ -74,8 +76,8 @@ class TCompactProtocol extends TProtocol { DoubleLinkedQueue _lastField = DoubleLinkedQueue(); int _lastFieldId = 0; - TField _booleanField; - bool _boolValue; + TField? _booleanField; + bool? _boolValue; final Uint8List tempList = Uint8List(10); final ByteData tempBD = ByteData(10); @@ -169,10 +171,9 @@ class TCompactProtocol extends TProtocol { @override void writeBool(bool b) { - if (b == null) b = false; if (_booleanField != null) { _writeFieldBegin( - _booleanField, b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE); + _booleanField!, b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE); _booleanField = null; } else { writeByte(b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE); @@ -181,40 +182,34 @@ class TCompactProtocol extends TProtocol { @override void writeByte(int b) { - if (b == null) b = 0; tempList[0] = b; transport.write(tempList, 0, 1); } @override void writeI16(int i16) { - if (i16 == null) i16 = 0; _writeVarInt32(_int32ToZigZag(Int32(i16))); } @override void writeI32(int i32) { - if (i32 == null) i32 = 0; _writeVarInt32(_int32ToZigZag(Int32(i32))); } @override void writeI64(int i64) { - if (i64 == null) i64 = 0; _writeVarInt64(_int64ToZigZag(Int64(i64))); } @override void writeDouble(double d) { - if (d == null) d = 0.0; tempBD.setFloat64(0, d, Endian.little); transport.write(tempBD.buffer.asUint8List(), 0, 8); } @override void writeString(String str) { - Uint8List bytes = - str != null ? _utf8Codec.encode(str) : Uint8List.fromList([]); + Uint8List bytes = _utf8Codec.encode(str); writeBinary(bytes); } @@ -374,7 +369,7 @@ class TCompactProtocol extends TProtocol { @override bool readBool() { if (_boolValue != null) { - bool result = _boolValue; + bool result = _boolValue!; _boolValue = null; return result; } diff --git a/lib/dart/lib/src/protocol/t_json_protocol.dart b/lib/dart/lib/src/protocol/t_json_protocol.dart index 4aaf20cd99f..9752a41c36b 100644 --- a/lib/dart/lib/src/protocol/t_json_protocol.dart +++ b/lib/dart/lib/src/protocol/t_json_protocol.dart @@ -32,15 +32,16 @@ class TJsonProtocol extends TProtocol { static const Utf8Codec utf8Codec = Utf8Codec(); - _BaseContext _context; - _BaseContext _rootContext; - _LookaheadReader _reader; + late _BaseContext _context; + late _BaseContext _rootContext; + late _LookaheadReader _reader; final List<_BaseContext> _contextStack = []; final Uint8List _tempBuffer = Uint8List(4); TJsonProtocol(TTransport transport) : super(transport) { _rootContext = _BaseContext(this); + _context = _rootContext; _reader = _LookaheadReader(this); _resetContext(); } @@ -122,8 +123,6 @@ class TJsonProtocol extends TProtocol { } void _writeJsonInteger(int i) { - if (i == null) i = 0; - _context.write(); String str = i.toString(); @@ -137,8 +136,6 @@ class TJsonProtocol extends TProtocol { } void _writeJsonDouble(double d) { - if (d == null) d = 0.0; - _context.write(); String str = d.toString(); bool escapeNumbers = d.isNaN || d.isInfinite || _context.escapeNumbers; @@ -267,7 +264,6 @@ class TJsonProtocol extends TProtocol { @override void writeBool(bool b) { - if (b == null) b = false; _writeJsonInteger(b ? 1 : 0); } @@ -298,7 +294,7 @@ class TJsonProtocol extends TProtocol { @override void writeString(String s) { - var bytes = s != null ? utf8Codec.encode(s) : Uint8List.fromList([]); + var bytes = utf8Codec.encode(s); _writeJsonString(bytes); } @@ -418,7 +414,7 @@ class TJsonProtocol extends TProtocol { Uint8List bytes = _readJsonString(skipContext: true); double d; try { - d = double.tryParse(utf8Codec.decode(bytes)); + d = double.parse(utf8Codec.decode(bytes)); } catch (_) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Bad data encounted in numeric data"); @@ -675,7 +671,7 @@ class _Constants { TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type"); } - return _TYPE_ID_TO_NAME_BYTES[typeId]; + return _TYPE_ID_TO_NAME_BYTES[typeId]!; } static final Map _NAME_TO_TYPE_ID = Map.unmodifiable({ @@ -699,7 +695,7 @@ class _Constants { TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type"); } - return _NAME_TO_TYPE_ID[name]; + return _NAME_TO_TYPE_ID[name]!; } static final Set _JSON_NUMERICS = Set.from([ diff --git a/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart b/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart index 693e58bbdfb..42030a81f9f 100644 --- a/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart +++ b/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart @@ -25,11 +25,7 @@ class TMultiplexedProtocol extends TProtocolDecorator { TMultiplexedProtocol(TProtocol protocol, String serviceName) : _serviceName = serviceName, - super(protocol) { - if (serviceName == null) { - throw ArgumentError.notNull("serviceName"); - } - } + super(protocol); @override void writeMessageBegin(TMessage message) { diff --git a/lib/dart/lib/src/serializer/t_deserializer.dart b/lib/dart/lib/src/serializer/t_deserializer.dart index c01ab6bdd97..f284ee63f0b 100644 --- a/lib/dart/lib/src/serializer/t_deserializer.dart +++ b/lib/dart/lib/src/serializer/t_deserializer.dart @@ -19,10 +19,10 @@ part of thrift; class TDeserializer { final message = TMessage('Deserializer', TMessageType.ONEWAY, 1); - TBufferedTransport transport; - TProtocol protocol; + late TBufferedTransport transport; + late TProtocol protocol; - TDeserializer({TProtocolFactory protocolFactory}) { + TDeserializer({TProtocolFactory? protocolFactory}) { this.transport = TBufferedTransport(); if (protocolFactory == null) { diff --git a/lib/dart/lib/src/serializer/t_serializer.dart b/lib/dart/lib/src/serializer/t_serializer.dart index fb897895d6d..17cab53a41c 100644 --- a/lib/dart/lib/src/serializer/t_serializer.dart +++ b/lib/dart/lib/src/serializer/t_serializer.dart @@ -19,10 +19,10 @@ part of thrift; class TSerializer { final message = TMessage('Serializer', TMessageType.ONEWAY, 1); - TBufferedTransport transport; - TProtocol protocol; + late TBufferedTransport transport; + late TProtocol protocol; - TSerializer({TProtocolFactory protocolFactory}) { + TSerializer({TProtocolFactory? protocolFactory}) { this.transport = TBufferedTransport(); if (protocolFactory == null) { diff --git a/lib/dart/lib/src/t_application_error.dart b/lib/dart/lib/src/t_application_error.dart index 38449a9a40b..69c0138f33c 100644 --- a/lib/dart/lib/src/t_application_error.dart +++ b/lib/dart/lib/src/t_application_error.dart @@ -45,7 +45,7 @@ class TApplicationError extends TError { static TApplicationError read(TProtocol iprot) { TField field; - String message; + String message = ""; int type = TApplicationErrorType.UNKNOWN; iprot.readStructBegin(); @@ -87,7 +87,7 @@ class TApplicationError extends TError { write(TProtocol oprot) { oprot.writeStructBegin(_struct); - if (message != null && message.isNotEmpty) { + if (message.isNotEmpty) { oprot.writeFieldBegin(_messageField); oprot.writeString(message); oprot.writeFieldEnd(); diff --git a/lib/dart/lib/src/transport/t_buffered_transport.dart b/lib/dart/lib/src/transport/t_buffered_transport.dart index f17b2eecfd5..f6c5ea6c339 100644 --- a/lib/dart/lib/src/transport/t_buffered_transport.dart +++ b/lib/dart/lib/src/transport/t_buffered_transport.dart @@ -20,7 +20,7 @@ part of thrift; /// Buffered implementation of [TTransport]. class TBufferedTransport extends TTransport { final List _writeBuffer = []; - Iterator _readIterator; + Iterator? _readIterator; Uint8List consumeWriteBuffer() { Uint8List buffer = Uint8List.fromList(_writeBuffer); @@ -29,7 +29,7 @@ class TBufferedTransport extends TTransport { } void _setReadBuffer(Uint8List readBuffer) { - _readIterator = readBuffer != null ? readBuffer.iterator : null; + _readIterator = readBuffer.iterator; } void _reset({bool isOpen = false}) { @@ -40,7 +40,7 @@ class TBufferedTransport extends TTransport { bool get hasReadData => _readIterator != null; - bool _isOpen; + bool _isOpen = false; @override bool get isOpen => _isOpen; @@ -56,10 +56,6 @@ class TBufferedTransport extends TTransport { @override int read(Uint8List buffer, int offset, int length) { - if (buffer == null) { - throw ArgumentError.notNull("buffer"); - } - if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); } @@ -69,13 +65,17 @@ class TBufferedTransport extends TTransport { } int i = 0; - while (i < length && _readIterator.moveNext()) { - buffer[offset + i] = _readIterator.current; + bool hasData = true; + while (i < length && hasData) { + hasData = _readIterator!.moveNext(); + if (hasData) { + buffer[offset + i] = _readIterator!.current; i++; + } } // cleanup iterator when we've reached the end - if (_readIterator.current == null) { + if (!hasData) { _readIterator = null; } @@ -84,10 +84,6 @@ class TBufferedTransport extends TTransport { @override void write(Uint8List buffer, int offset, int length) { - if (buffer == null) { - throw ArgumentError.notNull("buffer"); - } - if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); } diff --git a/lib/dart/lib/src/transport/t_framed_transport.dart b/lib/dart/lib/src/transport/t_framed_transport.dart index 3fc55fa096a..de09e51d69b 100644 --- a/lib/dart/lib/src/transport/t_framed_transport.dart +++ b/lib/dart/lib/src/transport/t_framed_transport.dart @@ -29,16 +29,12 @@ class TFramedTransport extends TBufferedTransport { int _receivedHeaderBytes = 0; int _bodySize = 0; - Uint8List _body; + Uint8List? _body; int _receivedBodyBytes = 0; - Completer _frameCompleter; + Completer? _frameCompleter; - TFramedTransport(TTransport transport) : _transport = transport { - if (transport == null) { - throw ArgumentError.notNull("transport"); - } - } + TFramedTransport(TTransport transport) : _transport = transport; @override bool get isOpen => _transport.isOpen; @@ -115,7 +111,7 @@ class TFramedTransport extends TBufferedTransport { void _readFrameBody() { var remainingBodyBytes = _bodySize - _receivedBodyBytes; - int got = _transport.read(_body, _receivedBodyBytes, remainingBodyBytes); + int got = _transport.read(_body!, _receivedBodyBytes, remainingBodyBytes); if (got < 0) { throw TTransportError( TTransportErrorType.UNKNOWN, "Socket closed during frame body read"); @@ -124,7 +120,7 @@ class TFramedTransport extends TBufferedTransport { _receivedBodyBytes += got; if (_receivedBodyBytes == _bodySize) { - var body = _body; + var body = _body!; _bodySize = 0; _body = null; @@ -134,7 +130,9 @@ class TFramedTransport extends TBufferedTransport { var completer = _frameCompleter; _frameCompleter = null; - completer.complete(Uint8List(0)); + if (completer != null) { + completer.complete(Uint8List(0)); + } } else { _registerForReadableBytes(); } @@ -154,7 +152,7 @@ class TFramedTransport extends TBufferedTransport { _registerForReadableBytes(); } - return _frameCompleter.future; + return _frameCompleter!.future; } void _registerForReadableBytes() { @@ -168,8 +166,9 @@ class TFramedTransport extends TBufferedTransport { _body = null; _receivedBodyBytes = 0; _frameCompleter = null; - - completer.completeError(e); + if (completer != null) { + completer.completeError(e); + } }); } } diff --git a/lib/dart/lib/src/transport/t_http_transport.dart b/lib/dart/lib/src/transport/t_http_transport.dart index 71fdb3cd977..cbd5242331b 100644 --- a/lib/dart/lib/src/transport/t_http_transport.dart +++ b/lib/dart/lib/src/transport/t_http_transport.dart @@ -33,9 +33,9 @@ class THttpClientTransport extends TBufferedTransport { final THttpConfig config; THttpClientTransport(this.httpClient, this.config) { - if (httpClient == null) { + /*if (httpClient == null) { throw ArgumentError.notNull("httpClient"); - } + }*/ } @override @@ -75,11 +75,11 @@ class THttpClientTransport extends TBufferedTransport { class THttpConfig { final Uri url; - Map _headers; + late Map _headers; Map get headers => _headers; THttpConfig(this.url, Map headers) { - if (url == null || !url.hasAuthority) { + if (!url.hasAuthority) { throw ArgumentError("Invalid url"); } @@ -89,9 +89,7 @@ class THttpConfig { void _initHeaders(Map initial) { var h = {}; - if (initial != null) { h.addAll(initial); - } h['Content-Type'] = 'application/x-thrift'; h['Accept'] = 'application/x-thrift'; diff --git a/lib/dart/lib/src/transport/t_message_reader.dart b/lib/dart/lib/src/transport/t_message_reader.dart index 620a27a9f97..afef386c82d 100644 --- a/lib/dart/lib/src/transport/t_message_reader.dart +++ b/lib/dart/lib/src/transport/t_message_reader.dart @@ -45,9 +45,9 @@ class TMessageReader { class _TMessageReaderTransport extends TTransport { _TMessageReaderTransport(); - Iterator _readIterator; + Iterator? _readIterator; - void reset(Uint8List bytes, [int offset = 0]) { + void reset(Uint8List? bytes, [int offset = 0]) { if (bytes == null) { _readIterator = null; return; @@ -57,11 +57,7 @@ class _TMessageReaderTransport extends TTransport { throw ArgumentError("The offset exceeds the bytes length"); } - _readIterator = bytes.iterator; - - for (var i = 0; i < offset; i++) { - _readIterator.moveNext(); - } + _readIterator = bytes.skip(offset).iterator; } @override @@ -75,9 +71,6 @@ class _TMessageReaderTransport extends TTransport { @override int read(Uint8List buffer, int offset, int length) { - if (buffer == null) { - throw ArgumentError.notNull("buffer"); - } if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); @@ -88,8 +81,8 @@ class _TMessageReaderTransport extends TTransport { } int i = 0; - while (i < length && _readIterator.moveNext()) { - buffer[offset + i] = _readIterator.current; + while (i < length && _readIterator!.moveNext()) { + buffer[offset + i] = _readIterator!.current; i++; } diff --git a/lib/dart/lib/src/transport/t_socket_transport.dart b/lib/dart/lib/src/transport/t_socket_transport.dart index d9929c89ba0..b568a8b6d67 100644 --- a/lib/dart/lib/src/transport/t_socket_transport.dart +++ b/lib/dart/lib/src/transport/t_socket_transport.dart @@ -34,10 +34,6 @@ abstract class TSocketTransport extends TBufferedTransport { /// A transport using the provided [socket]. TSocketTransport(this.socket) { - if (socket == null) { - throw ArgumentError.notNull('socket'); - } - socket.onError.listen((e) => logger.warning(e)); socket.onMessage.listen(handleIncomingMessage); } @@ -96,7 +92,7 @@ class TClientSocketTransport extends TSocketTransport { if (_completers.isNotEmpty) { var completer = _completers.removeAt(0); - completer.complete(); + completer.complete(Uint8List(0)); } } } @@ -134,15 +130,13 @@ class TAsyncClientSocketTransport extends TSocketTransport { var completer = Completer.sync(); _completers[seqid] = completer; - if (responseTimeout != null) { - Future.delayed(responseTimeout, () { - var completer = _completers.remove(seqid); - if (completer != null) { - completer.completeError( - TimeoutException("Response timed out.", responseTimeout)); - } - }); - } + Future.delayed(responseTimeout, () { + var completer = _completers.remove(seqid); + if (completer != null) { + completer.completeError( + TimeoutException("Response timed out.", responseTimeout)); + } + }); socket.send(bytes); @@ -156,7 +150,7 @@ class TAsyncClientSocketTransport extends TSocketTransport { TMessage message = messageReader.readMessage(messageBytes); var completer = _completers.remove(message.seqid); if (completer != null) { - completer.complete(); + completer.complete(Uint8List(0)); } } } diff --git a/lib/dart/pubspec.yaml b/lib/dart/pubspec.yaml index 7e205483adc..c05d3d11597 100644 --- a/lib/dart/pubspec.yaml +++ b/lib/dart/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: thrift -version: 0.20.0 +version: 0.23.0 description: > A Dart library for Apache Thrift author: Apache Thrift Developers @@ -24,20 +24,20 @@ homepage: http://thrift.apache.org documentation: http://thrift.apache.org environment: - sdk: ">=2.0.0 <3.0.0" + sdk: ">=2.12.0 <4.0.0" dependencies: fixnum: ">=0.10.2 <2.0.0" - http: ">=0.11.3 <0.14.0" + http: "^1.2.0" logging: ">=0.11.0 <2.0.0" dev_dependencies: build_runner: ">=1.7.1 <3.0.0" build_test: ">=0.10.9 <3.0.0" - build_vm_compilers: ^1.0.3 - build_web_compilers: ">=2.7.1 <4.0.0" - dart_dev: ^3.0.0 - dart_style: ">=1.3.1 <3.0.0" + build_vm_compilers: ^1.0.13 + build_web_compilers: ^3.2.7 + dart_dev: ^4.1.0 + dart_style: ^2.3.0 mockito: ">=4.1.1 <6.0.0" test: ^1.9.1 workiva_analysis_options: ^1.0.0 \ No newline at end of file diff --git a/lib/dart/test/protocol/t_protocol_test.dart b/lib/dart/test/protocol/t_protocol_test.dart index 15d973cab34..4b6ca092c65 100644 --- a/lib/dart/test/protocol/t_protocol_test.dart +++ b/lib/dart/test/protocol/t_protocol_test.dart @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. + library thrift.test.transport.t_json_protocol_test; import 'dart:async'; @@ -27,7 +28,7 @@ import 'package:thrift/thrift.dart'; void main() { final message = TMessage('my message', TMessageType.ONEWAY, 123); - TProtocol protocol; + late TProtocol protocol; Primitive getPrimitive(int tType) { switch (tType) { @@ -69,7 +70,7 @@ void main() { expect(output, input); } - Future primitiveNullTest(Primitive primitive) async { + /*Future primitiveNullTest(Primitive primitive) async { primitive.write(null); protocol.writeMessageEnd(); @@ -79,7 +80,7 @@ void main() { var output = primitive.read(); expect(output, primitive.defaultValue); - } + }*/ var sharedTests = () { test('Test message', () async { @@ -179,61 +180,61 @@ void main() { test('Test bool', () async { await primitiveTest(getPrimitive(TType.BOOL), true); }); - +/* test('Test bool null', () async { await primitiveNullTest(getPrimitive(TType.BOOL)); }); - +*/ test('Test byte', () async { await primitiveTest(getPrimitive(TType.BYTE), 64); }); - +/* test('Test byte null', () async { await primitiveNullTest(getPrimitive(TType.BYTE)); }); - +*/ test('Test I16', () async { await primitiveTest(getPrimitive(TType.I16), 32767); }); - +/* test('Test I16 null', () async { await primitiveNullTest(getPrimitive(TType.I16)); }); - +*/ test('Test I32', () async { await primitiveTest(getPrimitive(TType.I32), 2147483647); }); - +/* test('Test I32 null', () async { await primitiveNullTest(getPrimitive(TType.I32)); }); - +*/ test('Test I64', () async { await primitiveTest(getPrimitive(TType.I64), 9223372036854775807); }); - +/* test('Test I64 null', () async { await primitiveNullTest(getPrimitive(TType.I64)); }); - +*/ test('Test double', () async { await primitiveTest(getPrimitive(TType.DOUBLE), 3.1415926); }); - +/* test('Test double null', () async { await primitiveNullTest(getPrimitive(TType.DOUBLE)); }); - +*/ test('Test string', () async { var input = 'There are only two hard things in computer science: ' 'cache invalidation, naming things, and off-by-one errors.'; await primitiveTest(getPrimitive(TType.STRING), input); }); - +/* test('Test string null', () async { await primitiveNullTest(getPrimitive(TType.STRING)); }); - +*/ test('Test binary', () async { var input = Uint8List.fromList(List.filled(100, 123)); diff --git a/lib/dart/test/serializer/serializer_test.dart b/lib/dart/test/serializer/serializer_test.dart index 89883cb7c02..33df024ff19 100644 --- a/lib/dart/test/serializer/serializer_test.dart +++ b/lib/dart/test/serializer/serializer_test.dart @@ -25,9 +25,9 @@ import 'serializer_test_data.dart'; void main() { var serializer = () { - TDeserializer deserializer; - TSerializer serializer; - TestTObject testTObject; + TDeserializer deserializer = TDeserializer(); + TSerializer serializer = TSerializer(); + TestTObject testTObject = TestTObject(); setUp(() { serializer = TSerializer(); @@ -39,7 +39,7 @@ void main() { testTObject.d = 15.25; testTObject.i = 10; - var testList = List(); + var testList = []; testList.add("TEST 1"); testList.add("TEST 2"); diff --git a/lib/dart/test/serializer/serializer_test_data.dart b/lib/dart/test/serializer/serializer_test_data.dart index fc488f4e773..f5580ff60f9 100644 --- a/lib/dart/test/serializer/serializer_test_data.dart +++ b/lib/dart/test/serializer/serializer_test_data.dart @@ -30,15 +30,15 @@ class TestTObject implements TBase { static final TField _L_FIELD_DESC = TField("l", TType.LIST, 4); static final TField _B_FIELD_DESC = TField("b", TType.BOOL, 5); - int _i; + int? _i; static const int I = 1; - double _d; + double? _d; static const int D = 2; - String _s; + String? _s; static const int S = 3; - List _l; + List? _l; static const int L = 4; - bool _b; + bool? _b; static const int B = 5; bool __isset_i = false; @@ -48,9 +48,9 @@ class TestTObject implements TBase { TestTObject(); // i - int get i => this._i; + int? get i => this._i; - set i(int i) { + set i(int? i) { this._i = i; this.__isset_i = true; } @@ -62,9 +62,9 @@ class TestTObject implements TBase { } // d - double get d => this._d; + double? get d => this._d; - set d(double d) { + set d(double? d) { this._d = d; this.__isset_d = true; } @@ -76,9 +76,9 @@ class TestTObject implements TBase { } // s - String get s => this._s; + String? get s => this._s; - set s(String s) { + set s(String? s) { this._s = s; } @@ -89,9 +89,9 @@ class TestTObject implements TBase { } // l - List get l => this._l; + List? get l => this._l; - set l(List l) { + set l(List? l) { this._l = l; } @@ -102,9 +102,9 @@ class TestTObject implements TBase { } // b - bool get b => this._b; + bool? get b => this._b; - set b(bool b) { + set b(bool? b) { this._b = b; this.__isset_b = true; } @@ -134,13 +134,13 @@ class TestTObject implements TBase { } @override - setFieldValue(int fieldID, Object value) { + setFieldValue(int fieldID, Object? value) { switch (fieldID) { case I: if (value == null) { unsetI(); } else { - this.i = value; + this.i = value as int; } break; @@ -148,7 +148,7 @@ class TestTObject implements TBase { if (value == null) { unsetD(); } else { - this.d = value; + this.d = value as double; } break; @@ -156,7 +156,7 @@ class TestTObject implements TBase { if (value == null) { unsetS(); } else { - this.s = value; + this.s = value as String; } break; @@ -172,7 +172,7 @@ class TestTObject implements TBase { if (value == null) { unsetB(); } else { - this.b = value; + this.b = value as bool; } break; @@ -237,11 +237,11 @@ class TestTObject implements TBase { if (field.type == TType.LIST) { { TList _list74 = iprot.readListBegin(); - this.l = List(); + this.l = []; for (int _i75 = 0; _i75 < _list74.length; ++_i75) { String _elem76; _elem76 = iprot.readString(); - this.l.add(_elem76); + this.l?.add(_elem76); } iprot.readListEnd(); } @@ -275,21 +275,21 @@ class TestTObject implements TBase { oprot.writeStructBegin(_STRUCT_DESC); oprot.writeFieldBegin(_I_FIELD_DESC); - oprot.writeI32(this.i); + oprot.writeI32(this.i!); oprot.writeFieldEnd(); oprot.writeFieldBegin(_D_FIELD_DESC); - oprot.writeDouble(this.d); + oprot.writeDouble(this.d!); oprot.writeFieldEnd(); if (this.s != null) { oprot.writeFieldBegin(_S_FIELD_DESC); - oprot.writeString(this.s); + oprot.writeString(this.s!); oprot.writeFieldEnd(); } if (this.l != null) { oprot.writeFieldBegin(_L_FIELD_DESC); { - oprot.writeListBegin(TList(TType.STRING, this.l.length)); - for (var elem77 in this.l) { + oprot.writeListBegin(TList(TType.STRING, this.l!.length)); + for (var elem77 in this.l!) { oprot.writeString(elem77); } oprot.writeListEnd(); @@ -297,7 +297,7 @@ class TestTObject implements TBase { oprot.writeFieldEnd(); } oprot.writeFieldBegin(_B_FIELD_DESC); - oprot.writeBool(this.b); + oprot.writeBool(this.b!); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); diff --git a/lib/dart/test/t_application_error_test.dart b/lib/dart/test/t_application_error_test.dart index 848ce56a0e9..cecefc787fb 100644 --- a/lib/dart/test/t_application_error_test.dart +++ b/lib/dart/test/t_application_error_test.dart @@ -21,7 +21,7 @@ import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { - TProtocol protocol; + late TProtocol protocol; setUp(() { protocol = TBinaryProtocol(TBufferedTransport()); diff --git a/lib/dart/test/transport/t_framed_transport_test.dart b/lib/dart/test/transport/t_framed_transport_test.dart index d9a15a534c0..a028c6f50c1 100644 --- a/lib/dart/test/transport/t_framed_transport_test.dart +++ b/lib/dart/test/transport/t_framed_transport_test.dart @@ -28,10 +28,10 @@ void main() { group('TFramedTransport partial reads', () { final flushAwaitDuration = Duration(seconds: 10); - FakeReadOnlySocket socket; - TSocketTransport socketTransport; - TFramedTransport transport; - var messageAvailable; + late FakeReadOnlySocket socket; + late TSocketTransport socketTransport; + late TFramedTransport transport; + late bool messageAvailable; setUp(() { socket = FakeReadOnlySocket(); diff --git a/lib/dart/test/transport/t_http_transport_test.dart b/lib/dart/test/transport/t_http_transport_test.dart index 13f0ee98adf..d0d91f4af87 100644 --- a/lib/dart/test/transport/t_http_transport_test.dart +++ b/lib/dart/test/transport/t_http_transport_test.dart @@ -34,8 +34,8 @@ void main() { const utf8Codec = Utf8Codec(); group('THttpClientTransport', () { - FakeHttpClient client; - THttpClientTransport transport; + late FakeHttpClient client; + late THttpClientTransport transport; setUp(() { client = FakeHttpClient(sync: false); @@ -78,8 +78,8 @@ void main() { }); group('THttpClientTransport with multiple messages', () { - FakeHttpClient client; - THttpClientTransport transport; + late FakeHttpClient client; + late THttpClientTransport transport; setUp(() { client = FakeHttpClient(sync: true); @@ -88,7 +88,7 @@ void main() { }); test('Test read correct buffer after flush', () async { - String bufferText; + String bufferText= ""; var expectedText = 'response 1'; var expectedBytes = utf8Codec.encode(expectedText); @@ -124,8 +124,8 @@ class FakeHttpClient implements Client { @override Future post(url, - {Map headers, body, Encoding encoding}) { - postRequest = body; + {Map? headers, body, Encoding? encoding}) { + postRequest = body.toString(); var response = Response(postResponse, 200); if (sync) { @@ -136,33 +136,34 @@ class FakeHttpClient implements Client { } @override - Future head(url, {Map headers}) => + Future head(url, {Map? headers}) => throw UnimplementedError(); @override - Future get(url, {Map headers}) => + Future get(url, {Map? headers}) => throw UnimplementedError(); @override Future put(url, - {Map headers, body, Encoding encoding}) => + {Map? headers, body, Encoding? encoding}) => throw UnimplementedError(); @override Future patch(url, - {Map headers, body, Encoding encoding}) => + {Map? headers, body, Encoding? encoding}) => throw UnimplementedError(); @override - Future delete(url, {Map headers}) => + Future delete(Uri url, + {Map? headers, Object? body, Encoding? encoding}) => throw UnimplementedError(); @override - Future read(url, {Map headers}) => + Future read(url, {Map? headers}) => throw UnimplementedError(); @override - Future readBytes(url, {Map headers}) => + Future readBytes(url, {Map? headers}) => throw UnimplementedError(); @override diff --git a/lib/dart/test/transport/t_socket_transport_test.dart b/lib/dart/test/transport/t_socket_transport_test.dart index d46f5ede469..80edb6827b5 100644 --- a/lib/dart/test/transport/t_socket_transport_test.dart +++ b/lib/dart/test/transport/t_socket_transport_test.dart @@ -39,8 +39,8 @@ void main() { final framedResponseBase64 = base64.encode(_getFramedResponse(responseBytes)); group('TClientSocketTransport', () { - FakeSocket socket; - TTransport transport; + late FakeSocket socket; + late TTransport transport; setUp(() async { socket = FakeSocket(sync: false); @@ -74,8 +74,8 @@ void main() { }, timeout: Timeout(Duration(seconds: 1))); group('TClientSocketTransport with FramedTransport', () { - FakeSocket socket; - TTransport transport; + late FakeSocket socket; + late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); @@ -87,7 +87,7 @@ void main() { }); test('Test client sending data over framed transport', () async { - String bufferText; + String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); @@ -104,9 +104,9 @@ void main() { }, timeout: Timeout(Duration(seconds: 1))); group('TAsyncClientSocketTransport', () { - FakeSocket socket; - FakeProtocolFactory protocolFactory; - TTransport transport; + late FakeSocket socket; + late FakeProtocolFactory protocolFactory; + late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); @@ -122,7 +122,7 @@ void main() { }); test('Test response correlates to correct request', () async { - String bufferText; + String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); @@ -152,9 +152,9 @@ void main() { }, timeout: Timeout(Duration(seconds: 1))); group('TAsyncClientSocketTransport with TFramedTransport', () { - FakeSocket socket; - FakeProtocolFactory protocolFactory; - TTransport transport; + late FakeSocket socket; + late FakeProtocolFactory protocolFactory; + late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); @@ -173,7 +173,7 @@ void main() { }); test('Test async client sending data over framed transport', () async { - String bufferText; + String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); @@ -251,7 +251,7 @@ class FakeSocket extends TSocket { _onErrorController = StreamController.broadcast(sync: sync), _onMessageController = StreamController.broadcast(sync: sync); - bool _isOpen; + bool _isOpen = false; @override bool get isOpen => _isOpen; @@ -271,8 +271,8 @@ class FakeSocket extends TSocket { _onStateController.add(TSocketState.CLOSED); } - Uint8List _sendPayload; - Uint8List get sendPayload => _sendPayload; + Uint8List? _sendPayload; + Uint8List? get sendPayload => _sendPayload; @override void send(Uint8List data) { @@ -292,7 +292,7 @@ class FakeSocket extends TSocket { class FakeProtocolFactory implements TProtocolFactory { FakeProtocolFactory(); - TMessage message; + TMessage message = TMessage("", TMessageType.CALL, 0 /* seqid */); @override getProtocol(TTransport transport) => FakeProtocol(message); diff --git a/lib/dart/test/transport/t_transport_test.dart b/lib/dart/test/transport/t_transport_test.dart index 4758593a9f2..e60f61ddebb 100644 --- a/lib/dart/test/transport/t_transport_test.dart +++ b/lib/dart/test/transport/t_transport_test.dart @@ -25,16 +25,19 @@ void main() { group('TTransportFactory', () { test('transport is returned from base factory', () async { TTransport result; - TTransport transport; + TTransport? transport; var factory = TTransportFactory(); - result = await factory.getTransport(transport); - expect(result, isNull); + try { + result = await factory.getTransport(transport!); + expect(result, isNull); + } catch (e) { + expect(e, isA()); + } - transport = TBufferedTransport(); + transport = TBufferedTransport()..open(); result = await factory.getTransport(transport); - expect(result, transport); }); }); diff --git a/lib/delphi/src/Thrift.Collections.pas b/lib/delphi/src/Thrift.Collections.pas index 2cb2395adcc..0500d4936a2 100644 --- a/lib/delphi/src/Thrift.Collections.pas +++ b/lib/delphi/src/Thrift.Collections.pas @@ -191,127 +191,105 @@ TThriftListImpl = class( TInterfacedObject, IThriftList, IThriftContaine function ToString : string; override; end; - IThriftHashSet = interface(IThriftContainer) - ['{0923A3B5-D4D4-48A8-91AD-40238E2EAD66}'] - function GetEnumerator: TEnumerator; - function GetIsReadOnly: Boolean; + IThriftHashSet = interface(IThriftContainer) + ['{733E2B57-C374-4359-BBD5-2B9CD8DF737C}'] + function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; - property IsReadOnly: Boolean read GetIsReadOnly; - procedure Add( const item: TValue); + function Add( const item: T) : Boolean; procedure Clear; - function Contains( const item: TValue): Boolean; - procedure CopyTo(var A: TArray; arrayIndex: Integer); - function Remove( const item: TValue ): Boolean; + function Contains( const item: T): Boolean; + function Remove( const item: T): Boolean; end; // compatibility - IHashSet = interface( IThriftHashSet) + IHashSet = interface( IThriftHashSet) ['{C3CF557F-21D9-4524-B899-D3145B0389BB}'] end deprecated 'use IThriftHashSet'; {$WARN SYMBOL_DEPRECATED OFF} - TThriftHashSetImpl = class( TInterfacedObject, IHashSet, IThriftHashSet, IThriftContainer, ISupportsToString) + TThriftHashSetImpl = class( TInterfacedObject, IHashSet, IThriftHashSet, IThriftContainer, ISupportsToString) {$WARN SYMBOL_DEPRECATED DEFAULT} strict private - FDictionary : IThriftDictionary; - FIsReadOnly: Boolean; + FDictionary : TDictionary; // there is no THashSet in older Delphi versions strict protected - function GetEnumerator: TEnumerator; - function GetIsReadOnly: Boolean; + function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; - property IsReadOnly: Boolean read FIsReadOnly; - procedure Add( const item: TValue); + function Add( const item: T) : Boolean; procedure Clear; - function Contains( const item: TValue): Boolean; - procedure CopyTo(var A: TArray; arrayIndex: Integer); - function Remove( const item: TValue ): Boolean; + function Contains( const item: T): Boolean; + function Remove( const item: T): Boolean; public constructor Create( const aCapacity: Integer = 0); overload; - constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer); overload; + constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer); overload; + destructor Destroy; override; function ToString : string; override; end; // compatibility - THashSetImpl = class( TThriftHashSetImpl) + THashSetImpl = class( TThriftHashSetImpl) end deprecated 'use TThriftHashSetImpl'; implementation -{ TThriftHashSetImpl. } +{ TThriftHashSetImpl. } -procedure TThriftHashSetImpl.Add( const item: TValue); +function TThriftHashSetImpl.Add( const item: T) : Boolean; begin - if not FDictionary.ContainsKey(item) then - begin - FDictionary.Add( item, 0); - end; + result := not FDictionary.ContainsKey(item); + if result then FDictionary.Add( item, 0); end; -procedure TThriftHashSetImpl.Clear; +procedure TThriftHashSetImpl.Clear; begin FDictionary.Clear; end; -function TThriftHashSetImpl.Contains( const item: TValue): Boolean; +function TThriftHashSetImpl.Contains( const item: T): Boolean; begin Result := FDictionary.ContainsKey(item); end; -procedure TThriftHashSetImpl.CopyTo(var A: TArray; arrayIndex: Integer); -var - i : Integer; - Enumlator : TEnumerator; +constructor TThriftHashSetImpl.Create( const aCapacity: Integer); begin - Enumlator := GetEnumerator; - while Enumlator.MoveNext do - begin - A[arrayIndex] := Enumlator.Current; - Inc(arrayIndex); - end; + inherited Create; + FDictionary := TDictionary.Create( aCapacity); end; -constructor TThriftHashSetImpl.Create( const aCapacity: Integer); +constructor TThriftHashSetImpl.Create( const aCapacity: Integer; const aComparer : IEqualityComparer); begin inherited Create; - FDictionary := TThriftDictionaryImpl.Create( aCapacity); + FDictionary := TDictionary.Create( aCapacity, aComparer); end; -constructor TThriftHashSetImpl.Create( const aCapacity: Integer; const aComparer : IEqualityComparer); + +destructor TThriftHashSetImpl.Destroy; begin - inherited Create; - FDictionary := TThriftDictionaryImpl.Create( aCapacity, aComparer); + FDictionary.Free; + inherited Destroy; end; -function TThriftHashSetImpl.GetCount: Integer; + +function TThriftHashSetImpl.GetCount: Integer; begin Result := FDictionary.Count; end; -function TThriftHashSetImpl.GetEnumerator: TEnumerator; +function TThriftHashSetImpl.GetEnumerator: TEnumerator; begin Result := FDictionary.Keys.GetEnumerator; end; -function TThriftHashSetImpl.GetIsReadOnly: Boolean; -begin - Result := FIsReadOnly; -end; - -function TThriftHashSetImpl.Remove( const item: TValue): Boolean; +function TThriftHashSetImpl.Remove( const item: T): Boolean; begin - Result := False; - if FDictionary.ContainsKey( item ) then - begin - FDictionary.Remove( item ); - Result := not FDictionary.ContainsKey( item ); - end; + Result := FDictionary.ContainsKey( item); + if Result then FDictionary.Remove( item ); end; -function TThriftHashSetImpl.ToString : string; -var elm : TValue; +function TThriftHashSetImpl.ToString : string; +var elm : T; sb : TThriftStringBuilder; first : Boolean; begin @@ -323,7 +301,7 @@ function TThriftHashSetImpl.ToString : string; then first := FALSE else sb.Append(', '); - sb.Append( StringUtils.ToString(elm)); + sb.Append( StringUtils.ToString(elm)); end; sb.Append('}'); Result := sb.ToString; diff --git a/lib/delphi/src/Thrift.Configuration.pas b/lib/delphi/src/Thrift.Configuration.pas index 0cb11af350e..562dba16fef 100644 --- a/lib/delphi/src/Thrift.Configuration.pas +++ b/lib/delphi/src/Thrift.Configuration.pas @@ -33,33 +33,36 @@ interface type IThriftConfiguration = interface - ['{ADD75449-1A67-4B78-9B75-502A1E338CFC}'] - function GetRecursionLimit : Cardinal; - procedure SetRecursionLimit( const value : Cardinal); - function GetMaxFrameSize : Cardinal; - procedure SetMaxFrameSize( const value : Cardinal); - function GetMaxMessageSize : Cardinal; - procedure SetMaxMessageSize( const value : Cardinal); - - property RecursionLimit : Cardinal read GetRecursionLimit write SetRecursionLimit; - property MaxFrameSize : Cardinal read GetMaxFrameSize write SetMaxFrameSize; - property MaxMessageSize : Cardinal read GetMaxMessageSize write SetMaxMessageSize; + ['{666F7848-744A-4746-BDD5-43DC9B1D5520}'] + function GetRecursionLimit : Integer; + procedure SetRecursionLimit( const value : Integer); + function GetMaxFrameSize : Integer; + procedure SetMaxFrameSize( const value : Integer); + function GetMaxMessageSize : Integer; + procedure SetMaxMessageSize( const value : Integer); + + property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit; + property MaxFrameSize : Integer read GetMaxFrameSize write SetMaxFrameSize; + property MaxMessageSize : Integer read GetMaxMessageSize write SetMaxMessageSize; end; TThriftConfigurationImpl = class( TInterfacedObject, IThriftConfiguration) + strict private + class procedure ValidateLimitArgument( const value : Integer); inline; + strict protected FRecursionLimit : Cardinal; FMaxFrameSize : Cardinal; FMaxMessageSize : Cardinal; // IThriftConfiguration - function GetRecursionLimit : Cardinal; - procedure SetRecursionLimit( const value : Cardinal); - function GetMaxFrameSize : Cardinal; - procedure SetMaxFrameSize( const value : Cardinal); - function GetMaxMessageSize : Cardinal; - procedure SetMaxMessageSize( const value : Cardinal); + function GetRecursionLimit : Integer; + procedure SetRecursionLimit( const value : Integer); + function GetMaxFrameSize : Integer; + procedure SetMaxFrameSize( const value : Integer); + function GetMaxMessageSize : Integer; + procedure SetMaxMessageSize( const value : Integer); public constructor Create; @@ -82,39 +85,55 @@ constructor TThriftConfigurationImpl.Create; end; -function TThriftConfigurationImpl.GetRecursionLimit: Cardinal; +class procedure TThriftConfigurationImpl.ValidateLimitArgument( const value : Integer); +begin + if value <= 0 // zero makes not much sense either + then raise EArgumentOutOfRangeException.Create('Value must be positive'); +end; + + +function TThriftConfigurationImpl.GetRecursionLimit: Integer; begin - result := FRecursionLimit; + result := FRecursionLimit and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetRecursionLimit(const value: Cardinal); +procedure TThriftConfigurationImpl.SetRecursionLimit(const value: Integer); begin - FRecursionLimit := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FRecursionLimit := value and MAXINT; end; -function TThriftConfigurationImpl.GetMaxFrameSize: Cardinal; +function TThriftConfigurationImpl.GetMaxFrameSize: Integer; begin - result := FMaxFrameSize; + result := FMaxFrameSize and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetMaxFrameSize(const value: Cardinal); +procedure TThriftConfigurationImpl.SetMaxFrameSize(const value: Integer); begin - FMaxFrameSize := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FMaxFrameSize := value and MAXINT; end; -function TThriftConfigurationImpl.GetMaxMessageSize: Cardinal; +function TThriftConfigurationImpl.GetMaxMessageSize: Integer; begin - result := FMaxMessageSize; + result := FMaxMessageSize and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetMaxMessageSize(const value: Cardinal); +procedure TThriftConfigurationImpl.SetMaxMessageSize(const value: Integer); begin - FMaxMessageSize := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FMaxMessageSize := value and MAXINT; end; diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas index 80f1ce58abd..afb3dd52d24 100644 --- a/lib/delphi/src/Thrift.Protocol.Compact.pas +++ b/lib/delphi/src/Thrift.Protocol.Compact.pas @@ -176,6 +176,7 @@ TFactory = class( TInterfacedObject, IProtocolFactory) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const dub: Double); override; procedure WriteBinary( const b: TBytes); overload; override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; private // unit visible stuff @@ -542,6 +543,14 @@ procedure TCompactProtocolImpl.WriteBinary( const b: TBytes); Transport.Write( b); end; + +procedure TCompactProtocolImpl.WriteBinary( const bytes : IThriftBytes); +begin + WriteVarint32( Cardinal(bytes.Count)); + Transport.Write( bytes.QueryRawDataPtr, 0, bytes.Count); +end; + + procedure TCompactProtocolImpl.WriteUuid( const uuid: TGuid); var network : TGuid; // in network order (Big Endian) begin @@ -1002,8 +1011,8 @@ function TCompactProtocolImpl.GetMinSerializedSize( const aType : TType) : Integ // Return the minimum number of bytes a type will consume on the wire begin case aType of - TType.Stop: result := 0; - TType.Void: result := 0; + TType.Stop: result := 1; // T_STOP needs to count itself + TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := SizeOf(Byte); TType.Byte_: result := SizeOf(Byte); TType.Double_: result := 8; // uses fixedLongToBytes() which always writes 8 bytes @@ -1011,7 +1020,7 @@ function TCompactProtocolImpl.GetMinSerializedSize( const aType : TType) : Integ TType.I32: result := SizeOf(Byte); TType.I64: result := SizeOf(Byte); TType.String_: result := SizeOf(Byte); // string length - TType.Struct: result := 0; // empty struct + TType.Struct: result := 1; // empty struct needs at least 1 byte for the T_STOP TType.Map: result := SizeOf(Byte); // element count TType.Set_: result := SizeOf(Byte); // element count TType.List: result := SizeOf(Byte); // element count diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas index 2a9682ced11..5be7ae00cf3 100644 --- a/lib/delphi/src/Thrift.Protocol.JSON.pas +++ b/lib/delphi/src/Thrift.Protocol.JSON.pas @@ -1257,8 +1257,8 @@ function TJSONProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer; // Return the minimum number of bytes a type will consume on the wire begin case aType of - TType.Stop: result := 0; - TType.Void: result := 0; + TType.Stop: result := 1; // T_STOP needs to count itself + TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := 1; TType.Byte_: result := 1; TType.Double_: result := 1; diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas index f5cb454d4c1..ecf210361a2 100644 --- a/lib/delphi/src/Thrift.Protocol.pas +++ b/lib/delphi/src/Thrift.Protocol.pas @@ -28,6 +28,7 @@ interface Classes, SysUtils, Contnrs, + Math, Thrift.Exception, Thrift.Stream, Thrift.Utils, @@ -231,7 +232,6 @@ TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRe procedure WriteI64( const i64: Int64); procedure WriteDouble( const d: Double); procedure WriteString( const s: string ); - procedure WriteAnsiString( const s: AnsiString); procedure WriteBinary( const b: TBytes); overload; procedure WriteBinary( const b: IThriftBytes); overload; procedure WriteUuid( const uuid: TGuid); @@ -258,7 +258,6 @@ TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRe function ReadBinaryCOM : IThriftBytes; function ReadUuid: TGuid; function ReadString: string; - function ReadAnsiString: AnsiString; function NextRecursionLevel : IProtocolRecursionTracker; procedure IncrementRecursionDepth; @@ -310,7 +309,6 @@ TProtocolImpl = class abstract( TInterfacedObject, IProtocol) procedure WriteI64( const i64: Int64); virtual; abstract; procedure WriteDouble( const d: Double); virtual; abstract; procedure WriteString( const s: string ); virtual; - procedure WriteAnsiString( const s: AnsiString); virtual; procedure WriteBinary( const b: TBytes); overload; virtual; abstract; procedure WriteUuid( const b: TGuid); virtual; abstract; @@ -335,7 +333,6 @@ TProtocolImpl = class abstract( TInterfacedObject, IProtocol) function ReadBinary: TBytes; virtual; abstract; function ReadUuid: TGuid; virtual; abstract; function ReadString: string; virtual; - function ReadAnsiString: AnsiString; virtual; // provide generic implementation for all derived classes procedure WriteBinary( const bytes : IThriftBytes); overload; virtual; @@ -388,6 +385,7 @@ TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString) constructor Create; overload; constructor Create( const bytes : TBytes); overload; constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload; + constructor Create( const pData : Pointer; const nCount : Integer); overload; function ToString : string; override; end; @@ -441,6 +439,7 @@ TFactory = class( TInterfacedObject, IProtocolFactory) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteBinary( const b: TBytes); override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; function ReadMessageBegin: TThriftMessage; override; @@ -505,8 +504,8 @@ TProtocolDecorator = class( TProtocolImpl) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteString( const s: string ); override; - procedure WriteAnsiString( const s: AnsiString); override; procedure WriteBinary( const b: TBytes); override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; function ReadMessageBegin: TThriftMessage; override; @@ -530,7 +529,6 @@ TProtocolDecorator = class( TProtocolImpl) function ReadBinary: TBytes; override; function ReadUuid: TGuid; override; function ReadString: string; override; - function ReadAnsiString: AnsiString; override; end; @@ -682,21 +680,7 @@ function TProtocolImpl.Configuration : IThriftConfiguration; procedure TProtocolImpl.Reset; begin - FTrans.ResetConsumedMessageSize; -end; - -function TProtocolImpl.ReadAnsiString: AnsiString; -var - b : TBytes; - len : Integer; -begin - Result := ''; - b := ReadBinary; - len := Length( b ); - if len > 0 then begin - SetLength( Result, len); - System.Move( b[0], Pointer(Result)^, len ); - end; + FTrans.ResetMessageSizeAndConsumedBytes; end; function TProtocolImpl.ReadString: string; @@ -704,19 +688,6 @@ function TProtocolImpl.ReadString: string; Result := TEncoding.UTF8.GetString( ReadBinary ); end; -procedure TProtocolImpl.WriteAnsiString(const s: AnsiString); -var - b : TBytes; - len : Integer; -begin - len := Length(s); - SetLength( b, len); - if len > 0 then begin - System.Move( Pointer(s)^, b[0], len ); - end; - WriteBinary( b ); -end; - procedure TProtocolImpl.WriteString(const s: string); var b : TBytes; @@ -747,6 +718,8 @@ procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap); procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes); +// This implementation works, but is rather inefficient due to the extra memory allocation +// Consider overwriting this for your transport implementation var tmp : TBytes; begin SetLength( tmp, bytes.Count); @@ -802,6 +775,13 @@ constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : end; +constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer); +begin + SetLength(FData, Max(nCount,0)); + if Length(FData) > 0 then Move( pData^, FData[0], Length(FData)); +end; + + function TThriftBytesImpl.ToString : string; var sb : TThriftStringBuilder; begin @@ -1105,6 +1085,14 @@ procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes); if iLen > 0 then FTrans.Write(b, 0, iLen); end; +procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes); +var iLen : Integer; +begin + iLen := bytes.Count; + WriteI32( iLen); + if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen); +end; + procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid); var network : TGuid; // in network order (Big Endian) begin @@ -1249,8 +1237,8 @@ function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Intege // Return the minimum number of bytes a type will consume on the wire begin case aType of - TType.Stop: result := 0; - TType.Void: result := 0; + TType.Stop: result := 1; // T_STOP needs to count itself + TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := SizeOf(Byte); TType.Byte_: result := SizeOf(Byte); TType.Double_: result := SizeOf(Double); @@ -1258,7 +1246,7 @@ function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Intege TType.I32: result := SizeOf(Int32); TType.I64: result := SizeOf(Int64); TType.String_: result := SizeOf(Int32); // string length - TType.Struct: result := 0; // empty struct + TType.Struct: result := 1; // empty struct needs at least 1 byte for the T_STOP TType.Map: result := SizeOf(Int32); // element count TType.Set_: result := SizeOf(Int32); // element count TType.List: result := SizeOf(Int32); // element count @@ -1497,15 +1485,15 @@ procedure TProtocolDecorator.WriteString( const s: string ); end; -procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString); +procedure TProtocolDecorator.WriteBinary( const b: TBytes); begin - FWrappedProtocol.WriteAnsiString( s); + FWrappedProtocol.WriteBinary( b); end; -procedure TProtocolDecorator.WriteBinary( const b: TBytes); +procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes); begin - FWrappedProtocol.WriteBinary( b); + FWrappedProtocol.WriteBinary( bytes); end; @@ -1641,12 +1629,6 @@ function TProtocolDecorator.ReadString: string; end; -function TProtocolDecorator.ReadAnsiString: AnsiString; -begin - result := FWrappedProtocol.ReadAnsiString; -end; - - function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer; begin result := FWrappedProtocol.GetMinSerializedSize(aType); diff --git a/lib/delphi/src/Thrift.Serializer.pas b/lib/delphi/src/Thrift.Serializer.pas index 8ee8a3540dc..c354a37dacc 100644 --- a/lib/delphi/src/Thrift.Serializer.pas +++ b/lib/delphi/src/Thrift.Serializer.pas @@ -66,7 +66,7 @@ TDeserializer = class public constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol const aTransFact : ITransportFactory = nil; - const aConfig : IThriftConfiguration = nil); + const aConfig : IThriftConfiguration = nil); // DTOR destructor Destroy; override; @@ -74,6 +74,11 @@ TDeserializer = class // Deserialize the Thrift object data. procedure Deserialize( const input : TBytes; const target : IBase); overload; procedure Deserialize( const input : TStream; const target : IBase); overload; + + // helper + property Protocol : IProtocol read FProtocol; + property Transport : ITransport read FTransport; + property Stream : TThriftMemoryStream read FStream; end; @@ -164,14 +169,14 @@ procedure TSerializer.Serialize( const input : IBase; const aStm : TStream); constructor TDeserializer.Create( const aProtFact : IProtocolFactory; const aTransFact : ITransportFactory; - const aConfig : IThriftConfiguration); + const aConfig : IThriftConfiguration); var adapter : IThriftStream; protfact : IProtocolFactory; begin inherited Create; - FStream := TThriftMemoryStream.Create; - adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE); + FStream := TThriftMemoryStream.Create; + adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE); FTransport := TStreamTransportImpl.Create( adapter, nil, aConfig); if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport); @@ -205,8 +210,11 @@ procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase) try iBytes := Length(input); FStream.Size := iBytes; - if iBytes > 0 - then Move( input[0], FStream.Memory^, iBytes); + if iBytes > 0 then begin + Move( input[0], FStream.Memory^, iBytes); + Transport.ResetMessageSizeAndConsumedBytes(); // size has changed + Transport.UpdateKnownMessageSize(iBytes); + end; target.Read( FProtocol); finally @@ -221,9 +229,15 @@ procedure TDeserializer.Deserialize( const input : TStream; const target : IBase var before : Int64; begin try - before := FStream.Position; - FStream.CopyFrom( input, COPY_ENTIRE_STREAM); - FStream.Position := before; + if Assigned(input) then begin + before := FStream.Position; + ASSERT( before = 0); + FStream.CopyFrom( input, COPY_ENTIRE_STREAM); + FStream.Position := before; + Transport.ResetMessageSizeAndConsumedBytes(); // size has changed + Transport.UpdateKnownMessageSize(FStream.Size); + end; + target.Read( FProtocol); finally FStream.Size := 0; // free any allocated memory diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas index 6c1320d998e..56823312656 100644 --- a/lib/delphi/src/Thrift.Stream.pas +++ b/lib/delphi/src/Thrift.Stream.pas @@ -37,7 +37,7 @@ interface type IThriftStream = interface - ['{3A61A8A6-3639-4B91-A260-EFCA23944F3A}'] + ['{67801A9F-3B85-41CF-9025-D18AC6849B58}'] procedure Write( const buffer: TBytes; offset: Integer; count: Integer); overload; procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); overload; function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; overload; @@ -47,6 +47,7 @@ interface procedure Flush; function IsOpen: Boolean; function ToArray: TBytes; + function CanSeek : Boolean; function Size : Int64; function Position : Int64; end; @@ -66,6 +67,7 @@ TThriftStreamImpl = class abstract( TInterfacedObject, IThriftStream) procedure Flush; virtual; abstract; function IsOpen: Boolean; virtual; abstract; function ToArray: TBytes; virtual; abstract; + function CanSeek : Boolean; virtual; function Size : Int64; virtual; function Position : Int64; virtual; end; @@ -83,6 +85,7 @@ TThriftStreamAdapterDelphi = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -102,6 +105,7 @@ TThriftStreamAdapterCOM = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -176,6 +180,12 @@ procedure TThriftStreamAdapterCOM.Flush; end; end; +function TThriftStreamAdapterCOM.CanSeek : Boolean; +var statstg: TStatStg; +begin + result := IsOpen and Succeeded( FStream.Stat( statstg, STATFLAG_NONAME)); +end; + function TThriftStreamAdapterCOM.Size : Int64; var statstg: TStatStg; begin @@ -290,6 +300,11 @@ procedure TThriftStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: CheckSizeAndOffset( pBuf, offset+count, offset, count); end; +function TThriftStreamImpl.CanSeek : Boolean; +begin + result := FALSE; // TRUE indicates Size and Position are implemented +end; + function TThriftStreamImpl.Size : Int64; begin ASSERT(FALSE); @@ -332,6 +347,15 @@ procedure TThriftStreamAdapterDelphi.Flush; // nothing to do end; +function TThriftStreamAdapterDelphi.CanSeek : Boolean; +begin + try + result := IsOpen and (FStream.Size >= 0); // throws if not implemented + except + result := FALSE; // seek not implemented + end; +end; + function TThriftStreamAdapterDelphi.Size : Int64; begin result := FStream.Size; diff --git a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas index b0c7acd22cf..e3886a56bd0 100644 --- a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas +++ b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas @@ -53,6 +53,8 @@ TMsxmlHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) FCustomHeaders : IThriftDictionary; function CreateRequest: IXMLHTTPRequest; + class procedure EnsureSuccessHttpStatus( const aRequest : IXMLHTTPRequest); + strict protected function GetIsOpen: Boolean; override; procedure Open(); override; @@ -255,8 +257,9 @@ procedure TMsxmlHTTPClientImpl.SendRequest; ms.Position := 0; xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference ))); FInputStream := nil; + EnsureSuccessHttpStatus(xmlhttp); // throws if not FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream); - ResetConsumedMessageSize; + ResetMessageSizeAndConsumedBytes; UpdateKnownMessageSize( FInputStream.Size); finally ms.Free; @@ -271,6 +274,20 @@ procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); end; +class procedure TMsxmlHTTPClientImpl.EnsureSuccessHttpStatus( const aRequest : IXMLHTTPRequest); +var iStatus : Integer; + sText : string; +begin + if aRequest = nil + then raise TTransportExceptionNotOpen.Create('Invalid HTTP request data'); + + iStatus := aRequest.status; + sText := aRequest.statusText; + + if (200 > iStatus) or (iStatus > 299) + then raise TTransportExceptionEndOfFile.Create('HTTP '+IntToStr(iStatus)+' '+sText); +end; + end. diff --git a/lib/delphi/src/Thrift.Transport.Pipes.pas b/lib/delphi/src/Thrift.Transport.Pipes.pas index 44dfef78030..d3980d79811 100644 --- a/lib/delphi/src/Thrift.Transport.Pipes.pas +++ b/lib/delphi/src/Thrift.Transport.Pipes.pas @@ -679,22 +679,22 @@ procedure THandlePipeStreamImpl.Open; function TPipeTransportBase.GetIsOpen: Boolean; begin - result := (FInputStream <> nil) and (FInputStream.IsOpen) - and (FOutputStream <> nil) and (FOutputStream.IsOpen); + result := (InputStream <> nil) and (InputStream.IsOpen) + and (OutputStream <> nil) and (OutputStream.IsOpen); end; procedure TPipeTransportBase.Open; begin - FInputStream.Open; - FOutputStream.Open; + InputStream.Open; + OutputStream.Open; end; procedure TPipeTransportBase.Close; begin - FInputStream.Close; - FOutputStream.Close; + InputStream.Close; + OutputStream.Close; end; @@ -709,8 +709,8 @@ constructor TNamedPipeTransportClientEndImpl.Create( const aPipeName : string; // Named pipe constructor begin inherited Create( nil, nil, aConfig); - FInputStream := TNamedPipeStreamImpl.Create( aPipeName, TRUE, aShareMode, aSecurityAttributes, aTimeOut, aOpenTimeOut); - FOutputStream := FInputStream; // true for named pipes + SetInputStream( TNamedPipeStreamImpl.Create( aPipeName, TRUE, aShareMode, aSecurityAttributes, aTimeOut, aOpenTimeOut)); + SetOutputStream( InputStream); // true for named pipes end; @@ -721,8 +721,8 @@ constructor TNamedPipeTransportClientEndImpl.Create( const aPipe : THandle; // Named pipe constructor begin inherited Create( nil, nil, aConfig); - FInputStream := THandlePipeStreamImpl.Create( aPipe, aOwnsHandle, TRUE, aTimeOut); - FOutputStream := FInputStream; // true for named pipes + SetInputStream( THandlePipeStreamImpl.Create( aPipe, aOwnsHandle, TRUE, aTimeOut)); + SetOutputStream( InputStream); // true for named pipes end; @@ -761,8 +761,8 @@ constructor TAnonymousPipeTransportImpl.Create( const aPipeRead, aPipeWrite : TH begin inherited Create( nil, nil, aConfig); // overlapped is not supported with AnonPipes, see MSDN - FInputStream := THandlePipeStreamImpl.Create( aPipeRead, aOwnsHandles, FALSE, aTimeout); - FOutputStream := THandlePipeStreamImpl.Create( aPipeWrite, aOwnsHandles, FALSE, aTimeout); + SetInputStream( THandlePipeStreamImpl.Create( aPipeRead, aOwnsHandles, FALSE, aTimeout)); + SetOutputStream( THandlePipeStreamImpl.Create( aPipeWrite, aOwnsHandles, FALSE, aTimeout)); end; @@ -912,7 +912,7 @@ function TAnonymousPipeServerTransportImpl.CreateAnonPipe : Boolean; FReadHandle := hPipe; FWriteHandle := hPipeW; finally - if sd <> nil then LocalFree( Cardinal(sd)); + if sd <> nil then LocalFree( NativeUInt(sd)); end; end; @@ -1117,8 +1117,8 @@ function TNamedPipeServerTransportImpl.CreateNamedPipe : THandle; else raise TTransportExceptionNotOpen.Create('CreateNamedPipe() failed ' + IntToStr(GetLastError)); finally - if sd <> nil then LocalFree( Cardinal( sd)); - if acl <> nil then LocalFree( Cardinal( acl)); + if sd <> nil then LocalFree( NativeUInt(sd)); + if acl <> nil then LocalFree( NativeUInt(acl)); if everyone_sid <> nil then FreeSid(everyone_sid); end; end; diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas index 87a230996a2..5a6f2134415 100644 --- a/lib/delphi/src/Thrift.Transport.WinHTTP.pas +++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas @@ -51,6 +51,7 @@ TWinHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) function CreateRequest: IWinHTTPRequest; function SecureProtocolsAsWinHTTPFlags : Cardinal; + class procedure EnsureSuccessHttpStatus( const aRequest : IWinHTTPRequest); strict private type @@ -191,7 +192,8 @@ function TWinHTTPClientImpl.SecureProtocolsAsWinHTTPFlags : Cardinal; WINHTTP_FLAG_SECURE_PROTOCOL_SSL3, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1, - WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2, + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 ); var prot : TSecureProtocol; @@ -334,7 +336,8 @@ procedure TWinHTTPClientImpl.SendRequest; end; // we're about to receive a new message, so reset everyting - ResetConsumedMessageSize(-1); + ResetMessageSizeAndConsumedBytes(-1); + EnsureSuccessHttpStatus(http); // throws if not FInputStream := THTTPResponseStream.Create( http); if http.QueryTotalResponseSize( dwSize) // FALSE indicates "no info available" then UpdateKnownMessageSize( dwSize); @@ -349,6 +352,18 @@ procedure TWinHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); end; +class procedure TWinHTTPClientImpl.EnsureSuccessHttpStatus( const aRequest : IWinHTTPRequest); +var dwStatus : Cardinal; + sText : string; +begin + if (aRequest <> nil) + then aRequest.QueryHttpStatus( dwStatus, sText) + else raise TTransportExceptionNotOpen.Create('Invalid HTTP request data'); + + if (200 > dwStatus) or (dwStatus > 299) + then raise TTransportExceptionEndOfFile.Create('HTTP '+UIntToStr(dwStatus)+' '+sText); +end; + { TWinHTTPClientImpl.THTTPResponseStream } constructor TWinHTTPClientImpl.THTTPResponseStream.Create( const aRequest : IWinHTTPRequest); diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas index fd088375d42..6f9a93d64d6 100644 --- a/lib/delphi/src/Thrift.Transport.pas +++ b/lib/delphi/src/Thrift.Transport.pas @@ -68,7 +68,7 @@ interface function Configuration : IThriftConfiguration; function MaxMessageSize : Integer; - procedure ResetConsumedMessageSize( const knownSize : Int64 = -1); + procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); procedure CheckReadBytesAvailable( const numBytes : Int64); procedure UpdateKnownMessageSize( const size : Int64); end; @@ -106,10 +106,10 @@ TEndpointTransportBase = class abstract( TTransportBase, ITransport) function MaxMessageSize : Integer; property RemainingMessageSize : Int64 read FRemainingMessageSize; property KnownMessageSize : Int64 read FKnownMessageSize; - procedure ResetConsumedMessageSize( const newSize : Int64 = -1); + procedure ResetMessageSizeAndConsumedBytes( const newSize : Int64 = -1); procedure UpdateKnownMessageSize(const size : Int64); override; - procedure CheckReadBytesAvailable(const numBytes : Int64); inline; - procedure CountConsumedMessageBytes(const numBytes : Int64); inline; + procedure CheckReadBytesAvailable(const numBytes : Int64); {$IFNDEF Debug} inline; {$ENDIF} + procedure CountConsumedMessageBytes(const numBytes : Int64); {$IFNDEF Debug} inline; {$ENDIF} public constructor Create( const aConfig : IThriftConfiguration); reintroduce; end; @@ -124,7 +124,7 @@ TLayeredTransportBase = class abstract( TTransportBase, ITrans function Configuration : IThriftConfiguration; override; procedure UpdateKnownMessageSize( const size : Int64); override; function MaxMessageSize : Integer; inline; - procedure ResetConsumedMessageSize( const knownSize : Int64 = -1); inline; + procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); inline; procedure CheckReadBytesAvailable( const numBytes : Int64); virtual; public constructor Create( const aTransport: T); reintroduce; @@ -201,8 +201,14 @@ TTransportExceptionCorruptedData = class (TTransportExceptionSpecialized) end; TSecureProtocol = ( - SSL_2, SSL_3, TLS_1, // outdated, for compatibilty only - TLS_1_1, TLS_1_2 // secure (as of today) + // outdated, for compatibility only + SSL_2, + SSL_3, + TLS_1, + TLS_1_1, + // secure (as of today) + TLS_1_2, + TLS_1_3 ); TSecureProtocols = set of TSecureProtocol; @@ -303,14 +309,18 @@ TTcpSocketStreamImpl = class( TThriftStreamImpl) end; TStreamTransportImpl = class( TEndpointTransportBase, IStreamTransport) - strict protected - FInputStream : IThriftStream; - FOutputStream : IThriftStream; + strict private + FInternalInputStream : IThriftStream; + FInternalOutputStream : IThriftStream; + strict protected function GetIsOpen: Boolean; override; - function GetInputStream: IThriftStream; - function GetOutputStream: IThriftStream; + function GetInputStream: IThriftStream; inline; + procedure SetInputStream( const stream : IThriftStream); + + function GetOutputStream: IThriftStream; inline; + procedure SetOutputStream( const stream : IThriftStream); strict protected procedure Open; override; @@ -318,6 +328,8 @@ TStreamTransportImpl = class( TEndpointTransportBase, IStreamTransport) procedure Flush; override; function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override; procedure Write( const pBuf : Pointer; off, len : Integer); override; + + procedure UpdateKnownMessageSize(const size : Int64); override; public constructor Create( const aInputStream, aOutputStream : IThriftStream; const aConfig : IThriftConfiguration = nil); reintroduce; destructor Destroy; override; @@ -340,6 +352,7 @@ TBufferedStreamImpl = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -474,7 +487,13 @@ TFactory = class( TTransportFactoryImpl ) const - DEFAULT_THRIFT_SECUREPROTOCOLS = [ TSecureProtocol.TLS_1_1, TSecureProtocol.TLS_1_2]; + // From https://learn.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp- + // > TLS 1.3 is supported starting in Windows 11 and Windows Server 2022. + // > Enabling TLS 1.3 on earlier versions of Windows is not a safe system configuration. + DEFAULT_THRIFT_SECUREPROTOCOLS = [ + TSecureProtocol.TLS_1_2 + //TSecureProtocol.TLS_1_3 -- not supported on Win10 (see comment) + ]; implementation @@ -545,7 +564,7 @@ constructor TEndpointTransportBase.Create( const aConfig : IThriftConfiguration) then FConfiguration := aConfig else FConfiguration := TThriftConfigurationImpl.Create; - ResetConsumedMessageSize; + ResetMessageSizeAndConsumedBytes; end; @@ -562,7 +581,7 @@ function TEndpointTransportBase.MaxMessageSize : Integer; end; -procedure TEndpointTransportBase.ResetConsumedMessageSize( const newSize : Int64); +procedure TEndpointTransportBase.ResetMessageSizeAndConsumedBytes( const newSize : Int64); // Resets RemainingMessageSize to the configured maximum begin // full reset @@ -583,12 +602,12 @@ procedure TEndpointTransportBase.ResetConsumedMessageSize( const newSize : Int64 procedure TEndpointTransportBase.UpdateKnownMessageSize( const size : Int64); -// Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). +// Updates RemainingMessageSize to reflect the known real message size (e.g. framed transport). // Will throw if we already consumed too many bytes. var consumed : Int64; begin consumed := KnownMessageSize - RemainingMessageSize; - ResetConsumedMessageSize(size); + ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); end; @@ -642,9 +661,9 @@ function TLayeredTransportBase.MaxMessageSize : Integer; end; -procedure TLayeredTransportBase.ResetConsumedMessageSize( const knownSize : Int64 = -1); +procedure TLayeredTransportBase.ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); begin - InnerTransport.ResetConsumedMessageSize( knownSize); + InnerTransport.ResetMessageSizeAndConsumedBytes( knownSize); end; @@ -964,8 +983,8 @@ procedure TSocketImpl.Close; begin inherited Close; - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetOutputStream( nil); if FOwnsClient then FreeAndNil( FClient) @@ -997,8 +1016,8 @@ procedure TSocketImpl.InitSocket; FOwnsClient := True; stream := TTcpSocketStreamImpl.Create( FClient, FTimeout); - FInputStream := stream; - FOutputStream := stream; + SetInputStream( stream); + SetOutputStream( stream); end; procedure TSocketImpl.Open; @@ -1026,8 +1045,8 @@ procedure TSocketImpl.Open; FClient.Open; {$ENDIF} - FInputStream := TTcpSocketStreamImpl.Create( FClient, FTimeout); - FOutputStream := FInputStream; + SetInputStream( TTcpSocketStreamImpl.Create( FClient, FTimeout)); + SetOutputStream( InputStream); // same end; { TBufferedStream } @@ -1156,6 +1175,12 @@ procedure TBufferedStreamImpl.Write( const pBuf : Pointer; offset: Integer; coun end; +function TBufferedStreamImpl.CanSeek : Boolean; +begin + result := TRUE; +end; + + function TBufferedStreamImpl.Size : Int64; begin result := FReadBuffer.Size; @@ -1173,45 +1198,57 @@ function TBufferedStreamImpl.Position : Int64; constructor TStreamTransportImpl.Create( const aInputStream, aOutputStream : IThriftStream; const aConfig : IThriftConfiguration); begin inherited Create( aConfig); - FInputStream := aInputStream; - FOutputStream := aOutputStream; + SetInputStream( aInputStream); + SetOutputStream( aOutputStream); end; destructor TStreamTransportImpl.Destroy; begin - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetInputStream( nil); inherited; end; procedure TStreamTransportImpl.Close; begin - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetInputStream( nil); end; procedure TStreamTransportImpl.Flush; begin - if FOutputStream = nil then begin + if OutputStream = nil then begin raise TTransportExceptionNotOpen.Create('Cannot flush null outputstream' ); end; - FOutputStream.Flush; + OutputStream.Flush; end; function TStreamTransportImpl.GetInputStream: IThriftStream; begin - Result := FInputStream; + Result := FInternalInputStream; end; -function TStreamTransportImpl.GetIsOpen: Boolean; +procedure TStreamTransportImpl.SetInputStream( const stream : IThriftStream); begin - Result := True; + FInternalInputStream := stream; + ResetMessageSizeAndConsumedBytes(-1); // full reset to configured maximum + UpdateKnownMessageSize( -1); // adjust to real stream size end; function TStreamTransportImpl.GetOutputStream: IThriftStream; begin - Result := FOutputStream; + Result := FInternalOutputStream; +end; + +procedure TStreamTransportImpl.SetOutputStream( const stream : IThriftStream); +begin + FInternalOutputStream := stream; +end; + +function TStreamTransportImpl.GetIsOpen: Boolean; +begin + Result := True; end; procedure TStreamTransportImpl.Open; @@ -1221,19 +1258,36 @@ procedure TStreamTransportImpl.Open; function TStreamTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin - if FInputStream = nil + if InputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot read from null inputstream' ); - Result := FInputStream.Read( pBuf,buflen, off, len ); + Result := InputStream.Read( pBuf,buflen, off, len ); CountConsumedMessageBytes( result); end; procedure TStreamTransportImpl.Write( const pBuf : Pointer; off, len : Integer); begin - if FOutputStream = nil + if OutputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot write to null outputstream' ); - FOutputStream.Write( pBuf, off, len ); + OutputStream.Write( pBuf, off, len ); +end; + + +procedure TStreamTransportImpl.UpdateKnownMessageSize(const size : Int64); +var adjusted : Int64; +begin + if InputStream = nil + then adjusted := 0 + else begin + adjusted := MaxMessageSize; + if size > 0 + then adjusted := Math.Min( adjusted, size); + if InputStream.CanSeek + then adjusted := Math.Min( adjusted, InputStream.Size); + end; + + inherited UpdateKnownMessageSize( adjusted); end; { TBufferedTransportImpl } diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas index e6642d9f835..df132d7b213 100644 --- a/lib/delphi/src/Thrift.WinHTTP.pas +++ b/lib/delphi/src/Thrift.WinHTTP.pas @@ -197,27 +197,22 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; const - // WinHttpOpen dwAccessType values - WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0; - WINHTTP_ACCESS_TYPE_NO_PROXY = 1; - WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3; - - // flags for WinHttpOpen(): - WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage - - WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0; - // ports INTERNET_DEFAULT_PORT = 0; // use the protocol-specific default (80 or 443) + INTERNET_DEFAULT_HTTP_PORT = 80; + INTERNET_DEFAULT_HTTPS_PORT = 443; // flags for WinHttpOpenRequest(): WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS) WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion - WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header - WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE; WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query + WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header + WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE; + + // flags for WinHttpOpen(): + WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage // flags for WinHttpSendRequest(): WINHTTP_NO_PROXY_NAME = nil; @@ -252,10 +247,12 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; ICU_ESCAPE = $80000000; // (un)escape URL characters ICU_ESCAPE_AUTHORITY = $00002000; // causes InternetCreateUrlA to escape chars in authority components (user, pwd, host) - ICU_REJECT_USERPWD = $00004000; // rejects usrls whick have username/pwd sections + ICU_REJECT_USERPWD = $00004000; // rejects urls with username/pwd sections INTERNET_SCHEME_HTTP = INTERNET_SCHEME(1); INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2); + INTERNET_SCHEME_FTP = INTERNET_SCHEME(3); + INTERNET_SCHEME_SOCKS = INTERNET_SCHEME(4); // options manifests for WinHttp{Query|Set}Option WINHTTP_OPTION_CALLBACK = 1; @@ -275,6 +272,7 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; WINHTTP_OPTION_URL = 34; WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36; WINHTTP_OPTION_PROXY = 38; + WINHTTP_OPTION_PROXY_RESULT_ENTRY = 39; WINHTTP_OPTION_USER_AGENT = 41; WINHTTP_OPTION_CONTEXT_VALUE = 45; WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47; @@ -313,11 +311,77 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; WINHTTP_OPTION_SERVER_SPN_USED = 106; WINHTTP_OPTION_PROXY_SPN_USED = 107; WINHTTP_OPTION_SERVER_CBT = 108; - // options for newer WinHTTP versions + WINHTTP_OPTION_UNSAFE_HEADER_PARSING = 110; + WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111; + WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114; + WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115; + WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL = 116; WINHTTP_OPTION_DECOMPRESSION = 118; - // + WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122; + WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE = 123; + WINHTTP_OPTION_TCP_PRIORITY_HINT = 128; + WINHTTP_OPTION_CONNECTION_FILTER = 131; + WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133; + WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134; + WINHTTP_OPTION_KDC_PROXY_SETTINGS = 136; + WINHTTP_OPTION_ENCODE_EXTRA = 138; + WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139; + WINHTTP_OPTION_IPV6_FAST_FALLBACK = 140; + WINHTTP_OPTION_CONNECTION_STATS_V0 = 141; + WINHTTP_OPTION_REQUEST_TIMES = 142; + WINHTTP_OPTION_EXPIRE_CONNECTION = 143; + WINHTTP_OPTION_DISABLE_SECURE_PROTOCOL_FALLBACK = 144; + WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145; + WINHTTP_OPTION_REQUEST_STATS = 146; + WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT = 147; + WINHTTP_OPTION_CONNECTION_STATS_V1 = 150; + WINHTTP_OPTION_SECURITY_INFO = 151; + WINHTTP_OPTION_TCP_KEEPALIVE = 152; + WINHTTP_OPTION_TCP_FAST_OPEN = 153; + WINHTTP_OPTION_TCP_FALSE_START = 154; + WINHTTP_OPTION_IGNORE_CERT_REVOCATION_OFFLINE = 155; + WINHTTP_OPTION_TLS_PROTOCOL_INSECURE_FALLBACK = 158; + WINHTTP_OPTION_STREAM_ERROR_CODE = 159; + WINHTTP_OPTION_REQUIRE_STREAM_END = 160; + WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161; + WINHTTP_OPTION_FAILED_CONNECTION_RETRIES = 162; + WINHTTP_OPTION_HTTP2_KEEPALIVE = 164; + WINHTTP_OPTION_RESOLUTION_HOSTNAME = 165; + WINHTTP_OPTION_SET_TOKEN_BINDING = 166; + WINHTTP_OPTION_TOKEN_BINDING_PUBLIC_KEY = 167; + WINHTTP_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 168; + WINHTTP_OPTION_HTTP2_PLUS_TRANSFER_ENCODING = 169; + WINHTTP_OPTION_RESOLVER_CACHE_CONFIG = 170; + WINHTTP_OPTION_DISABLE_CERT_CHAIN_BUILDING = 171; + WINHTTP_OPTION_BACKGROUND_CONNECTIONS = 172; + WINHTTP_OPTION_FIRST_AVAILABLE_CONNECTION = 173; + WINHTTP_OPTION_TCP_PRIORITY_STATUS = 177; + WINHTTP_OPTION_CONNECTION_GUID = 178; + WINHTTP_OPTION_MATCH_CONNECTION_GUID = 179; + WINHTTP_OPTION_HTTP2_RECEIVE_WINDOW = 183; + WINHTTP_OPTION_FEATURE_SUPPORTED = 184; + WINHTTP_OPTION_QUIC_STATS = 185; + WINHTTP_OPTION_HTTP3_KEEPALIVE = 188; + WINHTTP_OPTION_HTTP3_HANDSHAKE_TIMEOUT = 189; + WINHTTP_OPTION_HTTP3_INITIAL_RTT = 190; + WINHTTP_OPTION_HTTP3_STREAM_ERROR_CODE = 191; + WINHTTP_OPTION_REQUEST_ANNOTATION = 192; + WINHTTP_OPTION_DISABLE_PROXY_AUTH_SCHEMES = 193; + WINHTTP_OPTION_REVERT_IMPERSONATION_SERVER_CERT = 194; + WINHTTP_OPTION_DISABLE_GLOBAL_POOLING = 195; + WINHTTP_OPTION_USE_SESSION_SCH_CRED = 196; + WINHTTP_OPTION_QUIC_STATS_V2 = 200; + WINHTTP_OPTION_QUIC_STREAM_STATS = 202; + WINHTTP_OPTION_USE_LOOKASIDE = 203; + WINHTTP_OPTION_ERROR_LOG_GUID = 204; + WINHTTP_OPTION_ENABLE_FAST_FORWARDING = 205; + WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_DATA = 206; + WINHTTP_OPTION_UPGRADE_TO_PROTOCOL = 207; + WINHTTP_OPTION_CONNECTION_STATS_V2 = 208; + WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS = 209; + WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK; - //WINHTTP_LAST_OPTION = WINHTTP_OPTION_SERVER_CBT; + //WINHTTP_LAST_OPTION = WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS; WINHTTP_OPTION_USERNAME = $1000; WINHTTP_OPTION_PASSWORD = $1001; @@ -384,6 +448,14 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; WINHTTP_DECOMPRESSION_FLAG_ALL = WINHTTP_DECOMPRESSION_FLAG_GZIP or WINHTTP_DECOMPRESSION_FLAG_DEFLATE; + // WinHttpOpen dwAccessType values + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0; + WINHTTP_ACCESS_TYPE_NO_PROXY = 1; + WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3; + WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4; + + WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0; + // values for WINHTTP_OPTION_SECURITY_FLAGS // query only @@ -473,6 +545,7 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; WINHTTP_QUERY_FLAG_REQUEST_HEADERS = $80000000; WINHTTP_QUERY_FLAG_SYSTEMTIME = $40000000; WINHTTP_QUERY_FLAG_NUMBER = $20000000; + WINHTTP_QUERY_FLAG_NUMBER64 = $08000000; // Secure connection error status flags WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = $00000001; @@ -489,19 +562,27 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = $00000080; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800; + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 = $00002000; - // Note: SECURE_PROTOCOL_ALL does not include TLS1.1 and higher! + // Note: SECURE_PROTOCOL_ALL does NOT include TLS1.1 and higher! WINHTTP_FLAG_SECURE_PROTOCOL_ALL = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 - or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; + or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; // AutoProxy WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001; WINHTTP_AUTOPROXY_CONFIG_URL = $00000002; WINHTTP_AUTOPROXY_HOST_KEEPCASE = $00000004; WINHTTP_AUTOPROXY_HOST_LOWERCASE = $00000008; + WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG = $00000100; + WINHTTP_AUTOPROXY_ALLOW_STATIC = $00000200; + WINHTTP_AUTOPROXY_ALLOW_CM = $00000400; WINHTTP_AUTOPROXY_RUN_INPROCESS = $00010000; WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = $00020000; + WINHTTP_AUTOPROXY_NO_DIRECTACCESS = $00040000; + WINHTTP_AUTOPROXY_NO_CACHE_CLIENT = $00080000; + WINHTTP_AUTOPROXY_NO_CACHE_SVC = $00100000; + WINHTTP_AUTOPROXY_SORT_RESULTS = $00400000; // Flags for dwAutoDetectFlags WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001; @@ -525,33 +606,41 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; ERROR_WINHTTP_CANNOT_CONNECT = WINHTTP_ERROR_BASE + 29; ERROR_WINHTTP_CONNECTION_ERROR = WINHTTP_ERROR_BASE + 30; ERROR_WINHTTP_RESEND_REQUEST = WINHTTP_ERROR_BASE + 32; + //ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; - see below + //ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; - see below ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = WINHTTP_ERROR_BASE + 44; - ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100; - ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101; - ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102; - ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103; + //ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; - see below + //ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; - see below + ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100; + ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101; + ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102; + ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103; ERROR_WINHTTP_HEADER_NOT_FOUND = WINHTTP_ERROR_BASE + 150; ERROR_WINHTTP_INVALID_SERVER_RESPONSE = WINHTTP_ERROR_BASE + 152; ERROR_WINHTTP_INVALID_HEADER = WINHTTP_ERROR_BASE + 153; ERROR_WINHTTP_INVALID_QUERY_REQUEST = WINHTTP_ERROR_BASE + 154; ERROR_WINHTTP_HEADER_ALREADY_EXISTS = WINHTTP_ERROR_BASE + 155; ERROR_WINHTTP_REDIRECT_FAILED = WINHTTP_ERROR_BASE + 156; - ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178; + //ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; - see below ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = WINHTTP_ERROR_BASE + 166; ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167; + //ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; - see below ERROR_WINHTTP_NOT_INITIALIZED = WINHTTP_ERROR_BASE + 172; ERROR_WINHTTP_SECURE_FAILURE = WINHTTP_ERROR_BASE + 175; + ERROR_WINHTTP_UNHANDLED_SCRIPT_TYPE = WINHTTP_ERROR_BASE + 176; + ERROR_WINHTTP_SCRIPT_EXECUTION_ERROR = WINHTTP_ERROR_BASE + 177; + ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178; // Certificate security errors. Additional information is provided // via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification. - ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; - ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; - ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; - ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; - ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; - ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; - ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170; - ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179; + ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; + ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; + ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; + ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; + ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; + ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; + ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170; + ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179; ERROR_WINHTTP_AUTODETECTION_FAILED = WINHTTP_ERROR_BASE + 180; ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = WINHTTP_ERROR_BASE + 181; @@ -560,8 +649,14 @@ function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = WINHTTP_ERROR_BASE + 184; ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = WINHTTP_ERROR_BASE + 185; ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = WINHTTP_ERROR_BASE + 186; + ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED_PROXY = WINHTTP_ERROR_BASE + 187; + ERROR_WINHTTP_SECURE_FAILURE_PROXY = WINHTTP_ERROR_BASE + 188; + ERROR_WINHTTP_RESERVED_189 = WINHTTP_ERROR_BASE + 189; + ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH = WINHTTP_ERROR_BASE + 190; + + WINHTTP_ERROR_LAST = ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH; + - WINHTTP_ERROR_LAST = WINHTTP_ERROR_BASE + 186; const diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas index 6696a195a57..4210615b0af 100644 --- a/lib/delphi/src/Thrift.pas +++ b/lib/delphi/src/Thrift.pas @@ -28,7 +28,7 @@ interface Thrift.Protocol; const - Version = '0.20.0'; + Version = '0.23.0'; type TException = Thrift.Exception.TException; // compatibility alias diff --git a/lib/delphi/test/client.dpr b/lib/delphi/test/client.dpr index eaeeee0a28d..db62995559e 100644 --- a/lib/delphi/test/client.dpr +++ b/lib/delphi/test/client.dpr @@ -24,9 +24,13 @@ program client; uses SysUtils, - DataFactory in 'Performance\DataFactory.pas', - PerfTests in 'Performance\PerfTests.pas', - TestClient in 'TestClient.pas', + ConsoleHelper in 'ConsoleHelper.pas', + TestConstants in 'testsuite\TestConstants.pas', + TestClient in 'testsuite\client\TestClient.pas', + TestLogger in 'testsuite\client\TestLogger.pas', + UnitTests in 'testsuite\client\UnitTests.pas', + PerfTests in 'testsuite\client\Performance\PerfTests.pas', + DataFactory in 'testsuite\client\Performance\DataFactory.pas', Thrift.Test in 'gen-delphi\Thrift.Test.pas', Thrift in '..\src\Thrift.pas', Thrift.Transport in '..\src\Thrift.Transport.pas', diff --git a/lib/delphi/test/client.dproj b/lib/delphi/test/client.dproj index ae6683d992d..ae31ba050e5 100644 --- a/lib/delphi/test/client.dproj +++ b/lib/delphi/test/client.dproj @@ -50,9 +50,13 @@ MainSource - - - + + + + + + + @@ -125,7 +129,7 @@ - --protocol=compact + --protocol=compact diff --git a/lib/delphi/test/codegen/README.md b/lib/delphi/test/codegen/README.md index a0145890f2e..65fbe4e510d 100644 --- a/lib/delphi/test/codegen/README.md +++ b/lib/delphi/test/codegen/README.md @@ -1,28 +1,15 @@ -How to use the test case: +Prerequisites ---------------------------------------------- -- copy and the template batch file -- open the batch file and adjust configuration as necessary -- run the batch - +- a suitable dcc32.exe must be reachable via normal search path +- the Thrift compiler thrift.exe is searched in this order + - under the `compiler` subdir, where debug is preferred over release + - otherwise via normal search path -Configuration: +How to use the test case: ---------------------------------------------- -SVNWORKDIR -should point to the Thrift working copy root - -MY_THRIFT_FILES -can be set to point to a folder with more thrift IDL files. -If you don't have any such files, just leave the setting blank. +- run the POSH script +- if any error messages occur, that's a bad sign +- there may be known but unfixed issues, these are listed accordingly -BIN -Local MSYS binary folder. Your THRIFT.EXE is installed here. -MINGW_BIN -Local MinGW bin folder. Contains DLL files required by THRIFT.EXE - -DCC -Identifies the Delphi Command Line compiler (dcc32.exe) -To be configuired only, if the default is not suitable. - ----------------------------------------------- -*EOF* \ No newline at end of file +*EOF* diff --git a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl deleted file mode 100644 index 79cf0e3396a..00000000000 --- a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl +++ /dev/null @@ -1,177 +0,0 @@ -REM /* -REM * Licensed to the Apache Software Foundation (ASF) under one -REM * or more contributor license agreements. See the NOTICE file -REM * distributed with this work for additional information -REM * regarding copyright ownership. The ASF licenses this file -REM * to you under the Apache License, Version 2.0 (the -REM * "License"); you may not use this file except in compliance -REM * with the License. You may obtain a copy of the License at -REM * -REM * http://www.apache.org/licenses/LICENSE-2.0 -REM * -REM * Unless required by applicable law or agreed to in writing, -REM * software distributed under the License is distributed on an -REM * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -REM * KIND, either express or implied. See the License for the -REM * specific language governing permissions and limitations -REM * under the License. -REM */ -@echo off -if ""=="%1" goto CONFIG -goto HANDLEDIR - -REM ----------------------------------------------------- -:CONFIG -REM ----------------------------------------------------- - -rem * CONFIGURATION BEGIN -rem * configuration settings, adjust as necessary to meet your system setup -set SVNWORKDIR= -set MY_THRIFT_FILES= -set BIN=C:\MSys10\local\bin -set MINGW_BIN=C:\MinGW\bin -set DCC= -set SUBDIR=gen-delphi -rem * CONFIGURATION END - - -REM ----------------------------------------------------- -:START -REM ----------------------------------------------------- - -rem * configured? -if "%SVNWORKDIR%"=="" goto CONFIG_ERROR - -rem * try to find dcc32.exe -echo Looking for dcc32.exe ... -if not exist "%DCC%" set DCC=%ProgramFiles%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe -if not exist "%DCC%" set DCC=%ProgramFiles(x86)%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe -if not exist "%DCC%" goto CONFIG_ERROR -echo Found %DCC% -echo. - -rem * some helpers -set PATH=%BIN%;%MINGW_BIN%;%PATH% -set TARGET=%SVNWORKDIR%\..\thrift-testing -set SOURCE=%SVNWORKDIR% -set TESTAPP=TestProject -set UNITSEARCH=%SOURCE%\lib\pas\src;%SOURCE%\lib\delphi\src -set OUTDCU="%TARGET%\dcu" -set LOGFILE=%TARGET%\%SUBDIR%\codegen.log - -rem * create and/or empty target dirs -if not exist "%TARGET%" md "%TARGET%" -if not exist "%TARGET%\%SUBDIR%" md "%TARGET%\%SUBDIR%" -if not exist "%OUTDCU%" md "%OUTDCU%" -if exist "%TARGET%\*.thrift" del "%TARGET%\*.thrift" /Q -if exist "%TARGET%\%SUBDIR%\*.*" del "%TARGET%\%SUBDIR%\*.*" /Q -if exist "%OUTDCU%\*.*" del "%OUTDCU%\*.*" /Q - -rem init logfile -echo Errors > "%LOGFILE%" -echo ---------------- >> "%LOGFILE%" - -rem * recurse through thrift WC and "my thrift files" folder -rem * copies all .thrift files into thrift-testing -call %0 %SOURCE% -if not "%MY_THRIFT_FILES%"=="" call %0 %MY_THRIFT_FILES% - -rem * compile all thrift files, generate PAS and C++ code -echo. -echo Generating code, please wait ... -cd "%TARGET%" -for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen delphi:register_types,constprefix,events,xmldoc "%%a" 2>> "%LOGFILE%" -REM * for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen cpp "%%a" >> NUL: -cmd /c start notepad "%LOGFILE%" -cd .. - -rem * check for special Delphi testcases being processed -if not exist "%TARGET%\%SUBDIR%\ReservedKeywords.pas" goto TESTCASE_MISSING - - -rem * generate a minimal DPR file that uses all generated pascal units -cd "%TARGET%\%SUBDIR%\" -if exist inherited.* ren inherited.* _inherited.* -echo program %TESTAPP%; > %TESTAPP%.dpr -echo {$APPTYPE CONSOLE} >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -echo uses >> %TESTAPP%.dpr -for %%a in (*.pas) do echo %%~na, >> %TESTAPP%.dpr -echo Windows, Classes, SysUtils; >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -echo begin >> %TESTAPP%.dpr -echo Writeln('Successfully compiled!'); >> %TESTAPP%.dpr -echo Writeln('List of units:'); >> %TESTAPP%.dpr -for %%a in (*.pas) do echo Write('%%~na':30,'':10); >> %TESTAPP%.dpr -echo Writeln; >> %TESTAPP%.dpr -echo end. >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -cd ..\.. - -rem * try to compile the DPR -rem * this should not throw any errors, warnings or hints -"%DCC%" -B "%TARGET%\%SUBDIR%\%TESTAPP%" -U"%UNITSEARCH%" -I"%UNITSEARCH%" -N"%OUTDCU%" -E"%TARGET%\%SUBDIR%" -dir "%TARGET%\%SUBDIR%\%TESTAPP%.exe" -if not exist "%TARGET%\%SUBDIR%\%TESTAPP%.exe" goto CODEGEN_FAILED -echo. -echo ----------------------------------------------------------------- -echo The compiled program is now executed. If it hangs or crashes, we -echo have a serious problem with the generated code. Expected output -echo is "Successfully compiled:" followed by a list of generated units. -echo ----------------------------------------------------------------- -"%TARGET%\%SUBDIR%\%TESTAPP%.exe" -echo ----------------------------------------------------------------- -echo. -pause -GOTO EOF - -REM ----------------------------------------------------- -:DXE_NOT_FOUND -REM ----------------------------------------------------- -echo Delphi Compiler (dcc32.exe) not found. -echo Please check the "DCC" setting in this batch. -echo. -cmd /c start notepad README.MD -cmd /c start notepad %0 -pause -GOTO EOF - - -REM ----------------------------------------------------- -:CONFIG_ERROR -REM ----------------------------------------------------- -echo Missing, incomplete or wrong configuration settings! -cmd /c start notepad README.MD -cmd /c start notepad %0 -pause -GOTO EOF - - -REM ----------------------------------------------------- -:TESTCASE_MISSING -REM ----------------------------------------------------- -echo Missing an expected Delphi testcase! -pause -GOTO EOF - - -REM ----------------------------------------------------- -:CODEGEN_FAILED -REM ----------------------------------------------------- -echo Code generation FAILED! -pause -GOTO EOF - - -REM ----------------------------------------------------- -:HANDLEDIR -REM ----------------------------------------------------- -REM echo %1 -for /D %%a in (%1\*) do call %0 %%a -if exist "%1\*.thrift" copy /b "%1\*.thrift" "%TARGET%\*.*" -GOTO EOF - - -REM ----------------------------------------------------- -:EOF -REM ----------------------------------------------------- diff --git a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 new file mode 100644 index 00000000000..f02afba3625 --- /dev/null +++ b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 @@ -0,0 +1,247 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#---- failing tests -------------------------------------------- + +# expected to fail at Thrift Compiler +$FAIL_THRIFT = @( + "BrokenConstants.thrift", # intended to break + "DuplicateImportsTest.thrift", # subdir includes don't work here + "Include.thrift") # subdir includes don't work here + +# expected to fail at Delphi Compiler +$FAIL_DELPHI = @( + "Thrift5320.thrift" # this conflicts with Delphi scopes, but it's a bad practice testcase anyway +) + +# unexpected but known bugs (TODO: fix them) +$KNOWN_BUGS = @( + "IgnoreInitialismsTest.thrift", + "NameConflictTest.thrift" + ) + + + +#---- functions -------------------------------------------- + +function FindThriftExe() { + # prefer debug over release over path + write-host -nonewline Looking for thrift.exe ... + $exe = "thrift.exe" + + # if we have a freshly compiled one it might be a better choice + @("Release","Debug") | foreach{ + if( test-path "$ROOTDIR\compiler\cpp\$_\thrift.exe") { $exe = "$ROOTDIR\compiler\cpp\$_\thrift.exe" } + if( test-path "$ROOTDIR\compiler\cpp\compiler\$_\thrift.exe") { $exe = "$ROOTDIR\compiler\cpp\$_\compiler\thrift.exe" } + } + + return $exe +} + + +function FindDcc32Exe() { + # prefer debug over release over path + write-host -nonewline Looking for dcc32.exe ... + $exe = "dcc32.exe" + + # TODO: add arbitraily complex code to locate a suitable dcc32.exe if it is not in the path + + return $exe +} + + +function InitializeFolder([string] $folder, [string] $pattern) { + #write-host $folder\$pattern + if(-not (test-path $folder)) { + new-item $folder -type directory | out-null + } + pushd $folder + remove-item $pattern #-recurse + popd +} + + +function CopyFilesFrom([string] $source, $text) { + #write-host "$source" + if( ($source -ne "") -and (test-path $source)) { + if( $text -ne $null) { + write-host -foregroundcolor yellow Copying $text ... + } + + pushd $source + # recurse dirs + gci . -directory | foreach { + CopyFilesFrom "$_" + } + # files within + gci *.thrift -file | foreach { + #write-host $_ + $name = $_.name + copy-item $_ "$TARGET\$name" + } + popd + } +} + +function TestIdlFile([string] $idl) { + # expected to fail at Thrift Compiler + $filter = $false + $FAIL_THRIFT | foreach { + if( $idl -eq $_) { + $filter = $true + write-host "Skipping $_" + } + } + if( $filter) { return $true } + + # compile IDL + #write-host -nonewline " $idl" + InitializeFolder "$TARGET\gen-delphi" "*.pas" + &$THRIFT_EXE $VERBOSE -r --gen delphi:register_types,constprefix,events,xmldoc $idl | out-file "$TARGET\thrift.log" + if( -not $?) { + get-content "$TARGET\thrift.log" | out-default + write-host -foregroundcolor red "Thrift compilation failed: $idl" + return $false + } + + # generate project dile + $units = gci "$TARGET\gen-delphi\*.pas" + $lines = @() + $lines += "program $TESTAPP;" + $lines += "{`$APPTYPE CONSOLE}" + $lines += "" + $lines += "uses" + $units | foreach { $name = $_.name.Replace(".pas",""); $lines += " $name," } + $lines += " Windows, Classes, SysUtils;" + $lines += "" + $lines += "begin" + $lines += " Writeln('Successfully compiled!');" + $lines += " Writeln('List of units:');" + $units | foreach { $name = $_.name.Replace(".pas",""); $lines += " Writeln('- $name');" } + $lines += " Writeln;" + $lines += "" + $lines += "end." + $lines += "" + $lines | set-content "$TARGET\gen-delphi\$TESTAPP.dpr" + + # try to compile the DPR + # this should not throw any errors, warnings or hints + $exe = "$TARGET\gen-delphi\$TESTAPP.exe" + if( test-path $exe) { remove-item $exe } + &$DCC32_EXE -B "$TARGET\gen-delphi\$TESTAPP" -U"$UNITSEARCH" -I"$UNITSEARCH" -N"$OUTDCU" -E"$TARGET\gen-delphi" | out-file "$TARGET\compile.log" + if( -not (test-path $exe)) { + + # expected to fail at Thrift Compiler + $filter = $false + $FAIL_DELPHI | foreach { + if( $idl -eq $_) { + $filter = $true + write-host ("Delphi compilation failed at "+$idl+" - as expected") + } + } + $KNOWN_BUGS | foreach { + if( $idl -eq $_) { + $filter = $true + write-host ("Delphi compilation failed at "+$idl+" - known issue (TODO)") + } + } + if( $filter) { return $true } + + get-content "$TARGET\compile.log" | out-default + write-host -foregroundcolor red "Delphi compilation failed: $idl" + return $false + } + + # The compiled program is now executed. If it hangs or crashes, we + # have a serious problem with the generated code. Expected output + # is "Successfully compiled:" followed by a list of generated units. + &"$exe" | out-file "$TARGET\exec.log" + if( -not $?) { + get-content "$TARGET\exec.log" | out-default + write-host -foregroundcolor red "Test execution failed: $idl" + return $false + } + return $true +} + +#---- main ------------------------------------------------- +# CONFIGURATION BEGIN +# configuration settings, adjust as necessary to meet your system setup +$MY_THRIFT_FILES = "" +$VERBOSE = "" # set any Thrift compiler debug/verbose flag you want + +# init +$ROOTDIR = $PSScriptRoot + "\..\..\..\.." + +# try to find thrift.exe +$THRIFT_EXE = FindThriftExe +&$THRIFT_EXE -version +if( -not $?) { + write-host -foregroundcolor red Missing thrift.exe + exit 1 +} + +# try to find dcc32.exe +$DCC32_EXE = FindDcc32Exe +&$DCC32_EXE --version +if( -not $?) { + write-host -foregroundcolor red Missing dcc32.exe + exit 1 +} + + +# some helpers +$TARGET = "$ROOTDIR\..\thrift-testing" +$TESTAPP = "TestProject" +$UNITSEARCH = "$ROOTDIR\lib\pas\src;$ROOTDIR\lib\delphi\src" +$OUTDCU = "$TARGET\dcu" + +# create and/or empty target dirs +InitializeFolder "$TARGET" "*.thrift" +InitializeFolder "$TARGET\gen-delphi" "*.pas" +InitializeFolder "$OUTDCU" "*.dcu" + +# recurse through thrift WC and "my thrift files" folder +# copies all .thrift files into thrift-testing +CopyFilesFrom "$ROOTDIR" "Thrift IDL files" +CopyFilesFrom "$MY_THRIFT_FILES" "Custom IDL files" + +# codegen and compile all thrift files, one by one to prevent side effects +$count = 0 +write-host -foregroundcolor yellow Running codegen tests .. +try { + pushd "$TARGET" + gci *.thrift -file | foreach { + $count += 1 + $ok = TestIdlFile $_.name + if( -not $ok) { + throw "TEST FAILED" # automated tests + popd; pause; pushd "$TARGET" # interactive / debug + } + } + write-host -foregroundcolor green "Success ($count tests executed)" + exit 0 +} catch { + write-host -foregroundcolor red $_ + exit 1 +} finally { + popd +} + +#eof diff --git a/lib/delphi/test/serializer/SerializerData.dpr b/lib/delphi/test/serializer/SerializerData.dpr index 92ed00b0094..637e4ed9925 100644 --- a/lib/delphi/test/serializer/SerializerData.dpr +++ b/lib/delphi/test/serializer/SerializerData.dpr @@ -40,6 +40,8 @@ uses Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', System_ in 'gen-delphi\System_.pas', SysUtils_ in 'gen-delphi\SysUtils_.pas', + test.ExceptionStruct in 'gen-delphi\test.ExceptionStruct.pas', + test.SimpleException in 'gen-delphi\test.SimpleException.pas', DebugProtoTest in 'gen-delphi\DebugProtoTest.pas', TestSerializer.Data in 'TestSerializer.Data.pas'; @@ -69,11 +71,26 @@ begin end; +function CreateBatchGetResponse : IBatchGetResponse; stdcall; +begin + result := Fixtures.CreateBatchGetResponse; +end; + + +function CreateSimpleException : IError; stdcall; +begin + result := Fixtures.CreateSimpleException; +end; + + exports CreateOneOfEach, CreateNesting, CreateHolyMoley, - CreateCompactProtoTestStruct; + CreateCompactProtoTestStruct, + CreateBatchGetResponse, + CreateSimpleException; + begin IsMultiThread := TRUE; diff --git a/lib/delphi/test/serializer/SerializerData.dproj b/lib/delphi/test/serializer/SerializerData.dproj index cfc27f8781d..ac744c143a1 100644 --- a/lib/delphi/test/serializer/SerializerData.dproj +++ b/lib/delphi/test/serializer/SerializerData.dproj @@ -85,6 +85,8 @@ + + @@ -100,10 +102,12 @@ - + - + Delphi.Personality.12 @@ -140,6 +144,9 @@ thrift.exe -r -gen delphi:com_types ..\..\..\..\test\DebugProtoTest.thrift]]>

SerializerData.dpr + + bin\Debug\Win32\TestSerializer.exe + True diff --git a/lib/delphi/test/serializer/SimpleException.thrift b/lib/delphi/test/serializer/SimpleException.thrift new file mode 100644 index 00000000000..c13876c8d74 --- /dev/null +++ b/lib/delphi/test/serializer/SimpleException.thrift @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +namespace * test.SimpleException + +exception Error { + 1: i32 ErrorCode = 42 + /** test name collision with Exception class */ + 2: Error InnerException + /** test name collisions with Thrift Delphi implementation details */ + 3: uuid ExceptionData = '00000000-4444-CCCC-ffff-0123456789ab' +} + + + +// EOF diff --git a/lib/delphi/test/serializer/TestSerializer.Data.pas b/lib/delphi/test/serializer/TestSerializer.Data.pas index 24f850d2f61..ddf4ba243eb 100644 --- a/lib/delphi/test/serializer/TestSerializer.Data.pas +++ b/lib/delphi/test/serializer/TestSerializer.Data.pas @@ -27,6 +27,8 @@ interface ComObj, Thrift.Protocol, Thrift.Collections, + test.ExceptionStruct, + test.SimpleException, DebugProtoTest; @@ -37,6 +39,8 @@ Fixtures = class class function CreateNesting : INesting; class function CreateHolyMoley : IHolyMoley; class function CreateCompactProtoTestStruct : ICompactProtoTestStruct; + class function CreateBatchGetResponse : IBatchGetResponse; + class function CreateSimpleException : IError; // These byte arrays are serialized versions of the above structs. // They were serialized in binary protocol using thrift 0.6.x and are used to @@ -359,6 +363,51 @@ class function Fixtures.CreateCompactProtoTestStruct : ICompactProtoTestStruct; end; +class function Fixtures.CreateBatchGetResponse : IBatchGetResponse; +var + data : IGetRequest; + error : ISomeException; +const + REQUEST_ID = '123'; +begin + data := TGetRequestImpl.Create; + data.Id := REQUEST_ID; + data.Data := TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes( #0#1#2#3#4#5#6#7#8)); + + error := TSomeExceptionImpl.Create; + error.Error := TErrorCode.GenericError; + + result := TBatchGetResponseImpl.Create; + result.Responses := TThriftDictionaryImpl.Create; + result.Responses.Add( REQUEST_ID, data); + result.Errors := TThriftDictionaryImpl.Create; + result.Errors.Add( REQUEST_ID, error); +end; + + +class function Fixtures.CreateSimpleException : IError; +var i : Integer; + inner : IError; + guid : TGuid; +const + IDL_GUID_VALUE : TGuid = '{00000000-4444-CCCC-ffff-0123456789ab}'; +begin + result := nil; + for i := 0 to 4 do begin + inner := result; + result := TErrorImpl.Create; + + // validate const values set in IDL + ASSERT( result.ErrorCode = 42); // IDL default value + ASSERT( IsEqualGUID( result.ExceptionData, IDL_GUID_VALUE)); + + // set fresh, but reproducible values + FillChar( guid, SizeOf(guid), i); + result.ErrorCode := i; + result.ExceptionData := guid; + result.InnerException := inner; + end; +end; end. diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas index 6ed1a48a2c5..7f5b829ec51 100644 --- a/lib/delphi/test/serializer/TestSerializer.Tests.pas +++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas @@ -41,13 +41,15 @@ interface Thrift.WinHTTP, Thrift.TypeRegistry, System_, + test.ExceptionStruct, + test.SimpleException, DebugProtoTest; {$TYPEINFO ON} type TFactoryPair = record - prot : IProtocolFactory; + proto : IProtocolFactory; trans : ITransportFactory; end; @@ -70,8 +72,9 @@ TTestSerializer = class //extends TestCase { class procedure Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair); overload; class procedure Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair); overload; - class procedure ValidateReadToEnd( const input : TBytes; const serial : TDeserializer); overload; - class procedure ValidateReadToEnd( const input : TStream; const serial : TDeserializer); overload; + class procedure Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair); overload; + + class procedure ValidateReadToEnd( const serial : TDeserializer); overload; class function LengthOf( const bytes : TBytes) : Integer; overload; inline; class function LengthOf( const bytes : IThriftBytes) : Integer; overload; inline; @@ -81,8 +84,15 @@ TTestSerializer = class //extends TestCase { procedure Test_Serializer_Deserializer; procedure Test_COM_Types; - procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); - procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_ThriftBytesCTORs; + + procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + + procedure Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream); + procedure Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream); public constructor Create; @@ -99,6 +109,8 @@ function CreateOneOfEach : IOneOfEach; stdcall; external SERIALIZERDATA_DLL; function CreateNesting : INesting; stdcall; external SERIALIZERDATA_DLL; function CreateHolyMoley : IHolyMoley; stdcall; external SERIALIZERDATA_DLL; function CreateCompactProtoTestStruct : ICompactProtoTestStruct; stdcall; external SERIALIZERDATA_DLL; +function CreateBatchGetResponse : IBatchGetResponse; stdcall; external SERIALIZERDATA_DLL; +function CreateSimpleException : IError; stdcall; external SERIALIZERDATA_DLL; { TTestSerializer } @@ -135,7 +147,7 @@ destructor TTestSerializer.Destroy; procedure TTestSerializer.AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory); var rec : TFactoryPair; begin - rec.prot := aProto; + rec.proto := aProto; rec.trans := aTrans; FProtocols.Add( rec); end; @@ -169,6 +181,53 @@ class function TTestSerializer.DataPtrOf( const bytes : IThriftBytes) : Pointer; end; +procedure TTestSerializer.Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream); +begin + Test_UuidDeserialization( factory, stream); + // add more tests here +end; + + +procedure TTestSerializer.Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream); + + function CreateGuidBytes : TBytes; + var obj : TObject; + i : Integer; + begin + obj := factory.proto as TObject; + + if obj is TJSONProtocolImpl.TFactory then begin + result := TEncoding.UTF8.GetBytes('"00112233-4455-6677-8899-aabbccddeeff"'); + Exit; + end; + + if (obj is TBinaryProtocolImpl.TFactory) + or (obj is TCompactProtocolImpl.TFactory) + then begin + SetLength(result,16); + for i := 0 to Length(result)-1 do result[i] := (i * $10) + i; + Exit; + end; + + raise Exception.Create('Unhandled case'); + end; + + +var tested, correct : TGuid; + bytes : TBytes; +begin + // write + bytes := CreateGuidBytes(); + + // init + read + Deserialize( bytes, tested, factory); + + // check + correct := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}'); + ASSERT( tested = correct); +end; + + procedure TTestSerializer.Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); var tested, correct : IOneOfEach; bytes : TBytes; @@ -265,6 +324,105 @@ procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const fact end; +procedure TTestSerializer.Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); +var tested, correct : IBatchGetResponse; + bytes : TBytes; + corrDP, testDP : TPair; + corrEP, testEP : TPair; +begin + // write + tested := CreateBatchGetResponse; + case method of + mt_Bytes: bytes := Serialize( tested, factory); + mt_Stream: begin + stream.Size := 0; + Serialize( tested, factory, stream); + end + else + ASSERT( FALSE); + end; + + // init + read + correct := TBatchGetResponseImpl.Create; + case method of + mt_Bytes: Deserialize( bytes, tested, factory); + mt_Stream: begin + stream.Position := 0; + Deserialize( stream, tested, factory); + end + else + ASSERT( FALSE); + end; + + // check + correct := CreateBatchGetResponse; + + // rewrite the following test if not + ASSERT( tested.Responses.Count = 1); + ASSERT( correct.Responses.Count = tested.Responses.Count); + for corrDP in correct.Responses do begin + for testDP in tested.Responses do begin + ASSERT( corrDP.Key = testDP.Key); + ASSERT( corrDP.Value.Id = testDP.Value.Id); + ASSERT( corrDP.Value.Data.Count = testDP.Value.Data.Count); + end; + end; + + // rewrite the following test if not + ASSERT( tested.Errors.Count = 1); + ASSERT( correct.Errors.Count = tested.Errors.Count); + for corrEP in correct.Errors do begin + for testEP in tested.Errors do begin + ASSERT( corrEP.Key = testEP.Key); + ASSERT( corrEP.Value.Error = testEP.Value.Error); + end; + end; +end; + + +procedure TTestSerializer.Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); +var tested, correct : IError; + bytes : TBytes; +begin + // write + tested := CreateSimpleException; + case method of + mt_Bytes: bytes := Serialize( tested, factory); + mt_Stream: begin + stream.Size := 0; + Serialize( tested, factory, stream); + end + else + ASSERT( FALSE); + end; + + // init + read + correct := TErrorImpl.Create; + case method of + mt_Bytes: Deserialize( bytes, tested, factory); + mt_Stream: begin + stream.Position := 0; + Deserialize( stream, tested, factory); + end + else + ASSERT( FALSE); + end; + + // check + correct := CreateSimpleException; + while correct <> nil do begin + // validate + ASSERT( correct.ErrorCode = tested.ErrorCode); + ASSERT( IsEqualGUID( correct.ExceptionData, tested.ExceptionData)); + + // iterate + correct := correct.InnerException; + tested := tested.InnerException; + ASSERT( (tested <> nil) xor (correct = nil)); // both or none + end; +end; + + procedure TTestSerializer.Test_Serializer_Deserializer; var factory : TFactoryPair; stream : TFileStream; @@ -278,8 +436,15 @@ procedure TTestSerializer.Test_Serializer_Deserializer; for factory in FProtocols do begin Writeln('- '+UserFriendlyName(factory)); - Test_OneOfEach( method, factory, stream); - Test_CompactStruct( method, factory, stream); + // protocol conformity tests + if (method = TMethod.mt_Bytes) and (factory.trans = nil) + then Test_ProtocolConformity( factory, stream); + + // normal objects + Test_OneOfEach( method, factory, stream); + Test_CompactStruct( method, factory, stream); + Test_ExceptionStruct( method, factory, stream); + Test_SimpleException( method, factory, stream); end; Writeln; @@ -293,7 +458,7 @@ procedure TTestSerializer.Test_Serializer_Deserializer; class function TTestSerializer.UserFriendlyName( const factory : TFactoryPair) : string; begin - result := Copy( (factory.prot as TObject).ClassName, 2, MAXINT); + result := Copy( (factory.proto as TObject).ClassName, 2, MAXINT); if factory.trans <> nil then result := Copy( (factory.trans as TObject).ClassName, 2, MAXINT) +' '+ result; @@ -325,11 +490,28 @@ procedure TTestSerializer.Test_COM_Types; end; +procedure TTestSerializer.Test_ThriftBytesCTORs; +var one, two : IThriftBytes; + bytes : TBytes; + sAscii : AnsiString; +begin + sAscii := 'ABC/xzy'; + bytes := TEncoding.ASCII.GetBytes(string(sAscii)); + + one := TThriftBytesImpl.Create( PAnsiChar(sAscii), Length(sAscii)); + two := TThriftBytesImpl.Create( bytes, TRUE); + + ASSERT( one.Count = two.Count); + ASSERT( CompareMem( one.QueryRawDataPtr, two.QueryRawDataPtr, one.Count)); +end; + + procedure TTestSerializer.RunTests; begin try Test_Serializer_Deserializer; Test_COM_Types; + Test_ThriftBytesCTORs; except on e:Exception do begin Writeln( e.ClassName+': '+ e.Message); @@ -346,7 +528,7 @@ class function TTestSerializer.Serialize(const input : IBase; const factory : TF config := TThriftConfigurationImpl.Create; //config.MaxMessageSize := 0; // we don't read anything here - serial := TSerializer.Create( factory.prot, factory.trans, config); + serial := TSerializer.Create( factory.proto, factory.trans, config); try result := serial.Serialize( input); finally @@ -362,7 +544,7 @@ class procedure TTestSerializer.Serialize(const input : IBase; const factory : T config := TThriftConfigurationImpl.Create; //config.MaxMessageSize := 0; // we don't read anything here - serial := TSerializer.Create( factory.prot, factory.trans, config); + serial := TSerializer.Create( factory.proto, factory.trans, config); try serial.Serialize( input, aStream); finally @@ -378,10 +560,10 @@ class procedure TTestSerializer.Deserialize( const input : TBytes; const target config := TThriftConfigurationImpl.Create; config.MaxMessageSize := Length(input); - serial := TDeserializer.Create( factory.prot, factory.trans, config); + serial := TDeserializer.Create( factory.proto, factory.trans, config); try serial.Deserialize( input, target); - ValidateReadToEnd( input, serial); + ValidateReadToEnd( serial); finally serial.Free; end; @@ -395,44 +577,49 @@ class procedure TTestSerializer.Deserialize( const input : TStream; const target config := TThriftConfigurationImpl.Create; config.MaxMessageSize := input.Size; - serial := TDeserializer.Create( factory.prot, factory.trans, config); + serial := TDeserializer.Create( factory.proto, factory.trans, config); try serial.Deserialize( input, target); - ValidateReadToEnd( input, serial); + ValidateReadToEnd( serial); finally serial.Free; end; end; -class procedure TTestSerializer.ValidateReadToEnd( const input : TBytes; const serial : TDeserializer); -// we should not have any more byte to read -var dummy : IBase; +class procedure TTestSerializer.Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair); +var serial : TDeserializer; + config : IThriftConfiguration; begin + config := TThriftConfigurationImpl.Create; + config.MaxMessageSize := Length(input); + + serial := TDeserializer.Create( factory.proto, factory.trans, config); try - dummy := TOneOfEachImpl.Create; - serial.Deserialize( input, dummy); - raise EInOutError.Create('Expected exception not thrown?'); - except - on e:TTransportExceptionEndOfFile do {expected}; - on e:Exception do raise; // unexpected + serial.Stream.Write(input[0], Length(input)); + serial.Stream.Position := 0; + serial.Transport.ResetMessageSizeAndConsumedBytes(); // size has changed + + target := serial.Protocol.ReadUuid; + finally + serial.Free; end; end; -class procedure TTestSerializer.ValidateReadToEnd( const input : TStream; const serial : TDeserializer); +class procedure TTestSerializer.ValidateReadToEnd( const serial : TDeserializer); // we should not have any more byte to read var dummy : IBase; begin try - input.Position := 0; dummy := TOneOfEachImpl.Create; - serial.Deserialize( input, dummy); + serial.Deserialize( nil, dummy); raise EInOutError.Create('Expected exception not thrown?'); except - on e:TTransportExceptionEndOfFile do {expected}; + on e:TTransportException do {expected}; on e:Exception do raise; // unexpected end; end; + end. diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr index b78c0db05d9..8c2f64d9e10 100644 --- a/lib/delphi/test/serializer/TestSerializer.dpr +++ b/lib/delphi/test/serializer/TestSerializer.dpr @@ -44,6 +44,8 @@ uses System_ in 'gen-delphi\System_.pas', SysUtils_ in 'gen-delphi\SysUtils_.pas', DebugProtoTest in 'gen-delphi\DebugProtoTest.pas', + test.ExceptionStruct in 'gen-delphi\test.ExceptionStruct.pas', + test.SimpleException in 'gen-delphi\test.SimpleException.pas', TestSerializer.Tests in 'TestSerializer.Tests.pas'; diff --git a/lib/delphi/test/serializer/TestSerializer.dproj b/lib/delphi/test/serializer/TestSerializer.dproj index 383e04a9547..1e348d5a89c 100644 --- a/lib/delphi/test/serializer/TestSerializer.dproj +++ b/lib/delphi/test/serializer/TestSerializer.dproj @@ -85,6 +85,8 @@ + + Cfg_2 @@ -99,10 +101,12 @@ - + +thrift.exe -r -gen delphi:com_types ..\..\..\..\test\DebugProtoTest.thrift +thrift.exe -r -gen delphi:com_types ..\..\..\..\test\ExceptionStruct.thrift +thrift.exe -r -gen delphi:com_types SimpleException.thrift]]> Delphi.Personality.12 diff --git a/lib/delphi/test/server.dpr b/lib/delphi/test/server.dpr index 79942816980..0cab02f3395 100644 --- a/lib/delphi/test/server.dpr +++ b/lib/delphi/test/server.dpr @@ -23,8 +23,9 @@ program server; uses SysUtils, - TestServer in 'TestServer.pas', - TestServerEvents in 'TestServerEvents.pas', + TestConstants in 'testsuite\TestConstants.pas', + TestServer in 'testsuite\server\TestServer.pas', + TestServerEvents in 'testsuite\server\TestServerEvents.pas', Thrift.Test in 'gen-delphi\Thrift.Test.pas', Thrift in '..\src\Thrift.pas', Thrift.Exception in '..\src\Thrift.Exception.pas', diff --git a/lib/delphi/test/server.dproj b/lib/delphi/test/server.dproj index 8e9b99dd72d..37ef9c9a6ed 100644 --- a/lib/delphi/test/server.dproj +++ b/lib/delphi/test/server.dproj @@ -50,8 +50,9 @@ MainSource - - + + + diff --git a/lib/delphi/test/TestConstants.pas b/lib/delphi/test/testsuite/TestConstants.pas similarity index 85% rename from lib/delphi/test/TestConstants.pas rename to lib/delphi/test/testsuite/TestConstants.pas index 9ac4808c056..e51b60084b9 100644 --- a/lib/delphi/test/TestConstants.pas +++ b/lib/delphi/test/testsuite/TestConstants.pas @@ -55,6 +55,18 @@ interface TLayeredTransports = set of TLayeredTransport; + {$SCOPEDENUMS ON} + TTestSize = ( + Empty, // Edge case: the zero-length empty binary + Normal, // Fairly small array of usual size (256 bytes) + ByteArrayTest, // THRIFT-4454 Large writes/reads may cause range check errors in debug mode + PipeWriteLimit, // THRIFT-4372 Pipe write operations across a network are limited to 65,535 bytes per write. + FifteenMB // quite a bit of data, but still below the default max frame size + ); + {$SCOPEDENUMS OFF} + + + const PROTOCOL_CLASSES : array[TKnownProtocol] of TProtocolImplClass = ( TBinaryProtocolImpl, @@ -151,6 +163,8 @@ interface function BytesToHex( const bytes : TBytes) : string; +function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; + implementation @@ -165,4 +179,38 @@ function BytesToHex( const bytes : TBytes) : string; end; +function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; +var i : Integer; +begin + case aSize of + TTestSize.Empty : SetLength( result, 0); + TTestSize.Normal : SetLength( result, $100); + TTestSize.ByteArrayTest : SetLength( result, SizeOf(TByteArray) + 128); + TTestSize.PipeWriteLimit : SetLength( result, 65535 + 128); + TTestSize.FifteenMB : SetLength( result, 15 * 1024 * 1024); + else + raise EArgumentException.Create('aSize'); + end; + + ASSERT( Low(result) = 0); + if Length(result) = 0 then Exit; + + // linear distribution, unless random is requested + if not aRandomDist then begin + for i := Low(result) to High(result) do begin + result[i] := i mod $100; + end; + Exit; + end; + + // random distribution of all 256 values + FillChar( result[0], Length(result) * SizeOf(result[0]), $0); + for i := Low(result) to High(result) do begin + result[i] := Byte( Random($100)); + end; +end; + + + + end. diff --git a/lib/delphi/test/Performance/DataFactory.pas b/lib/delphi/test/testsuite/client/Performance/DataFactory.pas similarity index 100% rename from lib/delphi/test/Performance/DataFactory.pas rename to lib/delphi/test/testsuite/client/Performance/DataFactory.pas diff --git a/lib/delphi/test/Performance/PerfTests.pas b/lib/delphi/test/testsuite/client/Performance/PerfTests.pas similarity index 100% rename from lib/delphi/test/Performance/PerfTests.pas rename to lib/delphi/test/testsuite/client/Performance/PerfTests.pas diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/testsuite/client/TestClient.pas similarity index 80% rename from lib/delphi/test/TestClient.pas rename to lib/delphi/test/testsuite/client/TestClient.pas index 1b09d3cf450..aca64410c17 100644 --- a/lib/delphi/test/TestClient.pas +++ b/lib/delphi/test/testsuite/client/TestClient.pas @@ -39,8 +39,10 @@ interface DateUtils, Generics.Collections, TestConstants, + TestLogger, ConsoleHelper, PerfTests, + UnitTests, Thrift, Thrift.Protocol.Compact, Thrift.Protocol.JSON, @@ -82,25 +84,6 @@ TTestSetup = record end; TClientThread = class( TThread ) - private type - TTestGroup = ( - test_Unknown, - test_BaseTypes, - test_Structs, - test_Containers, - test_Exceptions - // new values here - ); - TTestGroups = set of TTestGroup; - - TTestSize = ( - Empty, // Edge case: the zero-length empty binary - Normal, // Fairly small array of usual size (256 bytes) - ByteArrayTest, // THRIFT-4454 Large writes/reads may cause range check errors in debug mode - PipeWriteLimit, // THRIFT-4372 Pipe write operations across a network are limited to 65,535 bytes per write. - FifteenMB // quite a bit of data, but still below the default max frame size - ); - strict private FSetup : TTestSetup; FTransport : ITransport; @@ -109,18 +92,7 @@ TClientThread = class( TThread ) FThreadNo : Integer; FConsole : TThreadConsole; - - // test reporting, will be refactored out into separate class later - FTestGroup : string; - FCurrentTest : TTestGroup; - FSuccesses : Integer; - FErrors : TStringList; - FFailed : TTestGroups; - FExecuted : TTestGroups; - procedure StartTestGroup( const aGroup : string; const aTest : TTestGroup); - procedure Expect( aTestResult : Boolean; const aTestInfo : string); - procedure ReportResults; - function CalculateExitCode : Byte; + FLogger : ITestLogger; procedure ClientTest; {$IFDEF SupportsAsync} @@ -131,14 +103,13 @@ TClientThread = class( TThread ) procedure ShutdownProtocolTransportStack; function InitializeHttpTransport( const aTimeoutSetting : Integer; const aConfig : IThriftConfiguration = nil) : IHTTPClient; - procedure JSONProtocolReadWriteTest; - function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; {$IFDEF StressTest} procedure StressTest(const client : TThriftTest.Iface); {$ENDIF} - {$IFDEF Win64} - procedure UseInterlockedExchangeAdd64; - {$ENDIF} + + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); inline; + procedure Expect( aTestResult : Boolean; const aTestInfo : string); inline; + function CalculateExitCode : Byte; strict protected procedure Execute; override; @@ -174,7 +145,7 @@ implementation EXITCODE_FAILBIT_CONTAINERS = $04; EXITCODE_FAILBIT_EXCEPTIONS = $08; - MAP_FAILURES_TO_EXITCODE_BITS : array[TClientThread.TTestGroup] of Byte = ( + MAP_FAILURES_TO_EXITCODE_BITS : array[TClientTestGroup] of Byte = ( EXITCODE_SUCCESS, // no bits here EXITCODE_FAILBIT_BASETYPES, EXITCODE_FAILBIT_STRUCTS, @@ -1052,260 +1023,26 @@ procedure TClientThread.StressTest(const client : TThriftTest.Iface); {$ENDIF} -function TClientThread.PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; -var i : Integer; +procedure TClientThread.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); begin - case aSize of - Empty : SetLength( result, 0); - Normal : SetLength( result, $100); - ByteArrayTest : SetLength( result, SizeOf(TByteArray) + 128); - PipeWriteLimit : SetLength( result, 65535 + 128); - FifteenMB : SetLength( result, 15 * 1024 * 1024); - else - raise EArgumentException.Create('aSize'); - end; - - ASSERT( Low(result) = 0); - if Length(result) = 0 then Exit; - - // linear distribution, unless random is requested - if not aRandomDist then begin - for i := Low(result) to High(result) do begin - result[i] := i mod $100; - end; - Exit; - end; - - // random distribution of all 256 values - FillChar( result[0], Length(result) * SizeOf(result[0]), $0); - for i := Low(result) to High(result) do begin - result[i] := Byte( Random($100)); - end; -end; - - -{$IFDEF Win64} -procedure TClientThread.UseInterlockedExchangeAdd64; -var a,b : Int64; -begin - a := 1; - b := 2; - Thrift.Utils.InterlockedExchangeAdd64( a,b); - Expect( a = 3, 'InterlockedExchangeAdd64'); -end; -{$ENDIF} - - -procedure TClientThread.JSONProtocolReadWriteTest; -// Tests only then read/write procedures of the JSON protocol -// All tests succeed, if we can read what we wrote before -// Note that passing this test does not imply, that our JSON is really compatible to what -// other clients or servers expect as the real JSON. This is beyond the scope of this test. -var prot : IProtocol; - stm : TStringStream; - list : TThriftList; - config : IThriftConfiguration; - binary, binRead, emptyBinary : TBytes; - i,iErr : Integer; -const - TEST_SHORT = ShortInt( $FE); - TEST_SMALL = SmallInt( $FEDC); - TEST_LONG = LongInt( $FEDCBA98); - TEST_I64 = Int64( $FEDCBA9876543210); - TEST_DOUBLE = -1.234e-56; - DELTA_DOUBLE = TEST_DOUBLE * 1e-14; - TEST_STRING = 'abc-'#$00E4#$00f6#$00fc; // german umlauts (en-us: "funny chars") - // Test THRIFT-2336 and THRIFT-3404 with U+1D11E (G Clef symbol) and 'Русское Название'; - G_CLEF_AND_CYRILLIC_TEXT = #$1d11e' '#$0420#$0443#$0441#$0441#$043a#$043e#$0435' '#$041d#$0430#$0437#$0432#$0430#$043d#$0438#$0435; - G_CLEF_AND_CYRILLIC_JSON = '"\ud834\udd1e \u0420\u0443\u0441\u0441\u043a\u043e\u0435 \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"'; - // test both possible solidus encodings - SOLIDUS_JSON_DATA = '"one/two\/three"'; - SOLIDUS_EXCPECTED = 'one/two/three'; -begin - stm := TStringStream.Create; - try - StartTestGroup( 'JsonProtocolTest', test_Unknown); - - config := TThriftConfigurationImpl.Create; - - // prepare binary data - binary := PrepareBinaryData( FALSE, Normal); - SetLength( emptyBinary, 0); // empty binary data block - - // output setup - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); - - // write - Init( list, TType.String_, 9); - prot.WriteListBegin( list); - prot.WriteBool( TRUE); - prot.WriteBool( FALSE); - prot.WriteByte( TEST_SHORT); - prot.WriteI16( TEST_SMALL); - prot.WriteI32( TEST_LONG); - prot.WriteI64( TEST_I64); - prot.WriteDouble( TEST_DOUBLE); - prot.WriteString( TEST_STRING); - prot.WriteBinary( binary); - prot.WriteString( ''); // empty string - prot.WriteBinary( emptyBinary); // empty binary data block - prot.WriteListEnd; - - // input setup - Expect( stm.Position = stm.Size, 'Stream position/length after write'); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - - // read and compare - list := prot.ReadListBegin; - Expect( list.ElementType = TType.String_, 'list element type'); - Expect( list.Count = 9, 'list element count'); - Expect( prot.ReadBool, 'WriteBool/ReadBool: TRUE'); - Expect( not prot.ReadBool, 'WriteBool/ReadBool: FALSE'); - Expect( prot.ReadByte = TEST_SHORT, 'WriteByte/ReadByte'); - Expect( prot.ReadI16 = TEST_SMALL, 'WriteI16/ReadI16'); - Expect( prot.ReadI32 = TEST_LONG, 'WriteI32/ReadI32'); - Expect( prot.ReadI64 = TEST_I64, 'WriteI64/ReadI64'); - Expect( abs(prot.ReadDouble-TEST_DOUBLE) < abs(DELTA_DOUBLE), 'WriteDouble/ReadDouble'); - Expect( prot.ReadString = TEST_STRING, 'WriteString/ReadString'); - binRead := prot.ReadBinary; - Expect( Length(prot.ReadString) = 0, 'WriteString/ReadString (empty string)'); - Expect( Length(prot.ReadBinary) = 0, 'empty WriteBinary/ReadBinary (empty data block)'); - prot.ReadListEnd; - - // test binary data - Expect( Length(binary) = Length(binRead), 'Binary data length check'); - iErr := -1; - for i := Low(binary) to High(binary) do begin - if binary[i] <> binRead[i] then begin - iErr := i; - Break; - end; - end; - if iErr < 0 - then Expect( TRUE, 'Binary data check ('+IntToStr(Length(binary))+' Bytes)') - else Expect( FALSE, 'Binary data check at offset '+IntToStr(iErr)); - - Expect( stm.Position = stm.Size, 'Stream position after read'); - - - // Solidus can be encoded in two ways. Make sure we can read both - stm.Position := 0; - stm.Size := 0; - stm.WriteString(SOLIDUS_JSON_DATA); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = SOLIDUS_EXCPECTED, 'Solidus encoding'); - - - // Widechars should work too. Do they? - // After writing, we ensure that we are able to read it back - // We can't assume hex-encoding, since (nearly) any Unicode char is valid JSON - stm.Position := 0; - stm.Size := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); - prot.WriteString( G_CLEF_AND_CYRILLIC_TEXT); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Writing JSON with chars > 8 bit'); - - // Widechars should work with hex-encoding too. Do they? - stm.Position := 0; - stm.Size := 0; - stm.WriteString( G_CLEF_AND_CYRILLIC_JSON); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Reading JSON with chars > 8 bit'); - - - finally - stm.Free; - prot := nil; //-> Release - StartTestGroup( '', test_Unknown); // no more tests here - end; -end; - - -procedure TClientThread.StartTestGroup( const aGroup : string; const aTest : TTestGroup); -begin - FTestGroup := aGroup; - FCurrentTest := aTest; - - Include( FExecuted, aTest); - - if FTestGroup <> '' then begin - Console.WriteLine(''); - Console.WriteLine( aGroup+' tests'); - Console.WriteLine( StringOfChar('-',60)); - end; + FLogger.StartTestGroup( aGroup, aTest); end; procedure TClientThread.Expect( aTestResult : Boolean; const aTestInfo : string); begin - if aTestResult then begin - Inc(FSuccesses); - Console.WriteLine( aTestInfo+': passed'); - end - else begin - FErrors.Add( FTestGroup+': '+aTestInfo); - Include( FFailed, FCurrentTest); - Console.WriteLine( aTestInfo+': *** FAILED ***'); - - // We have a failed test! - // -> issue DebugBreak ONLY if a debugger is attached, - // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise - if IsDebuggerPresent - then {$IFDEF CPUX64} DebugBreak {$ELSE} asm int 3 end {$ENDIF}; - end; -end; - - -procedure TClientThread.ReportResults; -var nTotal : Integer; - sLine : string; -begin - // prevent us from stupid DIV/0 errors - nTotal := FSuccesses + FErrors.Count; - if nTotal = 0 then begin - Console.WriteLine('No results logged'); - Exit; - end; - - Console.WriteLine(''); - Console.WriteLine( StringOfChar('=',60)); - Console.WriteLine( IntToStr(nTotal)+' tests performed'); - Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)'); - Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)'); - Console.WriteLine( StringOfChar('=',60)); - if FErrors.Count > 0 then begin - Console.WriteLine('FAILED TESTS:'); - for sLine in FErrors do Console.WriteLine('- '+sLine); - Console.WriteLine( StringOfChar('=',60)); - InterlockedIncrement( ExitCode); // return <> 0 on errors - end; - Console.WriteLine(''); + FLogger.Expect( aTestResult, aTestInfo); end; function TClientThread.CalculateExitCode : Byte; -var test : TTestGroup; +var test : TClientTestGroup; + failed, executed : TClientTestGroups; begin result := EXITCODE_SUCCESS; - for test := Low(TTestGroup) to High(TTestGroup) do begin - if (test in FFailed) or not (test in FExecuted) + FLogger.QueryTestStats( failed, executed); + for test := Low(TClientTestGroup) to High(TClientTestGroup) do begin + if (test in failed) or not (test in executed) then result := result or MAP_FAILURES_TO_EXITCODE_BITS[test]; end; end; @@ -1318,12 +1055,7 @@ constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration FNumIterations := aNumIteration; FConsole := TThreadConsole.Create( Self, aLogThreadID); - FCurrentTest := test_Unknown; - - // error list: keep correct order, allow for duplicates - FErrors := TStringList.Create; - FErrors.Sorted := FALSE; - FErrors.Duplicates := dupAccept; + FLogger := TTestLoggerImpl.Create; inherited Create( TRUE); end; @@ -1331,7 +1063,7 @@ constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration destructor TClientThread.Destroy; begin FreeAndNil( FConsole); - FreeAndNil( FErrors); + FLogger := nil; //-> Release inherited; end; @@ -1341,10 +1073,9 @@ procedure TClientThread.Execute; begin // perform all tests try - {$IFDEF Win64} - UseInterlockedExchangeAdd64; - {$ENDIF} - JSONProtocolReadWriteTest; + // builtin (quick) unit tests on one thread only + if ThreadNo = 0 + then TQuickUnitTests.Execute(FLogger); // must be run in the context of the thread InitializeProtocolTransportStack; @@ -1357,7 +1088,7 @@ procedure TClientThread.Execute; end; // report the outcome - ReportResults; + FLogger.ReportResults; SetReturnValue( CalculateExitCode); finally diff --git a/lib/delphi/test/testsuite/client/TestLogger.pas b/lib/delphi/test/testsuite/client/TestLogger.pas new file mode 100644 index 00000000000..10ddfc74c1a --- /dev/null +++ b/lib/delphi/test/testsuite/client/TestLogger.pas @@ -0,0 +1,193 @@ +(* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *) + +unit TestLogger; + +{$I ../src/Thrift.Defines.inc} + +interface + +uses + Classes, Windows, SysUtils, Math, ActiveX, ComObj, + {$IFDEF SupportsAsync} System.Threading, {$ENDIF} + DateUtils, + Generics.Collections, + TestConstants, + ConsoleHelper, + Thrift, + Thrift.Protocol.Compact, + Thrift.Protocol.JSON, + Thrift.Protocol, + Thrift.Transport.Pipes, + Thrift.Transport.WinHTTP, + Thrift.Transport.MsxmlHTTP, + Thrift.Transport, + Thrift.Stream, + Thrift.Test, + Thrift.WinHTTP, + Thrift.Utils, + Thrift.Configuration, + Thrift.Collections; + + +type + TClientTestGroup = ( + test_Unknown, + test_BaseTypes, + test_Structs, + test_Containers, + test_Exceptions + // new values here + ); + TClientTestGroups = set of TClientTestGroup; + + + ITestLogger = interface + ['{26693ED5-1469-48AD-B1F3-04281B053DD4}'] + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); + procedure Expect( aTestResult : Boolean; const aTestInfo : string); + procedure QueryTestStats( out failed, executed : TClientTestGroups); + procedure ReportResults; + end; + + + // test reporting helper + TTestLoggerImpl = class( TInterfacedObject, ITestLogger) + strict private + FTestGroup : string; + FCurrentTest : TClientTestGroup; + FSuccesses : Integer; + FErrors : TStringList; + FFailed : TClientTestGroups; + FExecuted : TClientTestGroups; + + strict protected + // ITestLogger = interface + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); + procedure Expect( aTestResult : Boolean; const aTestInfo : string); + procedure QueryTestStats( out failed, executed : TClientTestGroups); + procedure ReportResults; + + public + constructor Create; + destructor Destroy; override; + + end; + + +implementation + + +constructor TTestLoggerImpl.Create; +begin + inherited Create; + FCurrentTest := test_Unknown; + + // error list: keep correct order, allow for duplicates + FErrors := TStringList.Create; + FErrors.Sorted := FALSE; + FErrors.Duplicates := dupAccept; +end; + + +destructor TTestLoggerImpl.Destroy; +begin + try + FreeAndNil( FErrors); + finally + inherited Destroy; + end; +end; + + +procedure TTestLoggerImpl.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); +begin + FTestGroup := aGroup; + FCurrentTest := aTest; + + Include( FExecuted, aTest); + + if FTestGroup <> '' then begin + Console.WriteLine(''); + Console.WriteLine( aGroup+' tests'); + Console.WriteLine( StringOfChar('-',60)); + end; +end; + + +procedure TTestLoggerImpl.Expect( aTestResult : Boolean; const aTestInfo : string); +begin + if aTestResult then begin + Inc(FSuccesses); + Console.WriteLine( aTestInfo+': passed'); + end + else begin + FErrors.Add( FTestGroup+': '+aTestInfo); + Include( FFailed, FCurrentTest); + Console.WriteLine( aTestInfo+': *** FAILED ***'); + + // We have a failed test! + // -> issue DebugBreak ONLY if a debugger is attached, + // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise + if IsDebuggerPresent + then {$IFDEF CPUX64} DebugBreak {$ELSE} asm int 3 end {$ENDIF}; + end; +end; + + +procedure TTestLoggerImpl.QueryTestStats( out failed, executed : TClientTestGroups); +begin + failed := FFailed; + executed := FExecuted; +end; + + + +procedure TTestLoggerImpl.ReportResults; +var nTotal : Integer; + sLine : string; +begin + // prevent us from stupid DIV/0 errors + nTotal := FSuccesses + FErrors.Count; + if nTotal = 0 then begin + Console.WriteLine('No results logged'); + Exit; + end; + + Console.WriteLine(''); + Console.WriteLine( StringOfChar('=',60)); + Console.WriteLine( IntToStr(nTotal)+' tests performed'); + Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)'); + Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)'); + Console.WriteLine( StringOfChar('=',60)); + if FErrors.Count > 0 then begin + Console.WriteLine('FAILED TESTS:'); + for sLine in FErrors do Console.WriteLine('- '+sLine); + Console.WriteLine( StringOfChar('=',60)); + InterlockedIncrement( ExitCode); // return <> 0 on errors + end; + Console.WriteLine(''); +end; + + + + + + +end. diff --git a/lib/delphi/test/testsuite/client/UnitTests.pas b/lib/delphi/test/testsuite/client/UnitTests.pas new file mode 100644 index 00000000000..3726c873594 --- /dev/null +++ b/lib/delphi/test/testsuite/client/UnitTests.pas @@ -0,0 +1,350 @@ +(* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *) + +unit UnitTests; + +{$I ../src/Thrift.Defines.inc} + +interface + +uses + Classes, Windows, SysUtils, Math, ActiveX, ComObj, + {$IFDEF SupportsAsync} System.Threading, {$ENDIF} + DateUtils, + Generics.Collections, + TestConstants, + TestLogger, + ConsoleHelper, + Thrift, + Thrift.Protocol.Compact, + Thrift.Protocol.JSON, + Thrift.Protocol, + Thrift.Transport.Pipes, + Thrift.Transport.WinHTTP, + Thrift.Transport.MsxmlHTTP, + Thrift.Transport, + Thrift.Stream, + Thrift.Test, + Thrift.WinHTTP, + Thrift.Utils, + Thrift.Configuration, + Thrift.Collections; + +type + TQuickUnitTests = class sealed + strict private + FLogger : ITestLogger; + + strict protected + // Helper + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); inline; + procedure Expect( aTestResult : Boolean; const aTestInfo : string); inline; + + // Test impl + procedure JSONProtocolReadWriteTest; + procedure HashSetTest; + {$IFDEF Win64} + procedure UseInterlockedExchangeAdd64; + {$ENDIF} + + // main execution part + constructor Create( const logger : ITestLogger); reintroduce; + procedure Execute; overload; + public + destructor Destroy; override; + + class procedure Execute( const logger : ITestLogger); overload; static; + end; + + +implementation + + +constructor TQuickUnitTests.Create( const logger : ITestLogger); +begin + inherited Create; + FLogger := logger; +end; + + +destructor TQuickUnitTests.Destroy; +begin + try + FLogger := nil; //-> Release + finally + inherited Destroy; + end; +end; + + +class procedure TQuickUnitTests.Execute( const logger : ITestLogger); +var instance : TQuickUnitTests; +begin + instance := TQuickUnitTests.Create(logger); + try + instance.Execute; + finally + instance.Free; + end; +end; + + +procedure TQuickUnitTests.Execute; +begin + {$IFDEF Win64} + UseInterlockedExchangeAdd64; + {$ENDIF} + + JSONProtocolReadWriteTest; + HashSetTest; +end; + + +procedure TQuickUnitTests.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); +begin + FLogger.StartTestGroup( aGroup, aTest); +end; + + +procedure TQuickUnitTests.Expect( aTestResult : Boolean; const aTestInfo : string); +begin + FLogger.Expect( aTestResult, aTestInfo); +end; + + +{$IFDEF Win64} +procedure TQuickUnitTests.UseInterlockedExchangeAdd64; +var a,b : Int64; +begin + a := 1; + b := 2; + Thrift.Utils.InterlockedExchangeAdd64( a,b); + Expect( a = 3, 'InterlockedExchangeAdd64'); +end; +{$ENDIF} + + +procedure TQuickUnitTests.JSONProtocolReadWriteTest; +// Tests only then read/write procedures of the JSON protocol +// All tests succeed, if we can read what we wrote before +// Note that passing this test does not imply, that our JSON is really compatible to what +// other clients or servers expect as the real JSON. This is beyond the scope of this test. +var prot : IProtocol; + stm : TStringStream; + list : TThriftList; + config : IThriftConfiguration; + binary, binRead, emptyBinary : TBytes; + i,iErr : Integer; +const + TEST_SHORT = ShortInt( $FE); + TEST_SMALL = SmallInt( $FEDC); + TEST_LONG = LongInt( $FEDCBA98); + TEST_I64 = Int64( $FEDCBA9876543210); + TEST_DOUBLE = -1.234e-56; + DELTA_DOUBLE = TEST_DOUBLE * 1e-14; + TEST_STRING = 'abc-'#$00E4#$00f6#$00fc; // german umlauts (en-us: "funny chars") + // Test THRIFT-2336 and THRIFT-3404 with U+1D11E (G Clef symbol) and 'Русское Название'; + G_CLEF_AND_CYRILLIC_TEXT = #$1d11e' '#$0420#$0443#$0441#$0441#$043a#$043e#$0435' '#$041d#$0430#$0437#$0432#$0430#$043d#$0438#$0435; + G_CLEF_AND_CYRILLIC_JSON = '"\ud834\udd1e \u0420\u0443\u0441\u0441\u043a\u043e\u0435 \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"'; + // test both possible solidus encodings + SOLIDUS_JSON_DATA = '"one/two\/three"'; + SOLIDUS_EXCPECTED = 'one/two/three'; +begin + stm := TStringStream.Create; + try + FLogger.StartTestGroup( 'JsonProtocolTest', test_Unknown); + + config := TThriftConfigurationImpl.Create; + + // prepare binary data + binary := PrepareBinaryData( FALSE, TTestSize.Normal); + SetLength( emptyBinary, 0); // empty binary data block + + // output setup + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); + + // write + Init( list, TType.String_, 9); + prot.WriteListBegin( list); + prot.WriteBool( TRUE); + prot.WriteBool( FALSE); + prot.WriteByte( TEST_SHORT); + prot.WriteI16( TEST_SMALL); + prot.WriteI32( TEST_LONG); + prot.WriteI64( TEST_I64); + prot.WriteDouble( TEST_DOUBLE); + prot.WriteString( TEST_STRING); + prot.WriteBinary( binary); + prot.WriteString( ''); // empty string + prot.WriteBinary( emptyBinary); // empty binary data block + prot.WriteListEnd; + + // input setup + Expect( stm.Position = stm.Size, 'Stream position/length after write'); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + + // read and compare + list := prot.ReadListBegin; + Expect( list.ElementType = TType.String_, 'list element type'); + Expect( list.Count = 9, 'list element count'); + Expect( prot.ReadBool, 'WriteBool/ReadBool: TRUE'); + Expect( not prot.ReadBool, 'WriteBool/ReadBool: FALSE'); + Expect( prot.ReadByte = TEST_SHORT, 'WriteByte/ReadByte'); + Expect( prot.ReadI16 = TEST_SMALL, 'WriteI16/ReadI16'); + Expect( prot.ReadI32 = TEST_LONG, 'WriteI32/ReadI32'); + Expect( prot.ReadI64 = TEST_I64, 'WriteI64/ReadI64'); + Expect( abs(prot.ReadDouble-TEST_DOUBLE) < abs(DELTA_DOUBLE), 'WriteDouble/ReadDouble'); + Expect( prot.ReadString = TEST_STRING, 'WriteString/ReadString'); + binRead := prot.ReadBinary; + Expect( Length(prot.ReadString) = 0, 'WriteString/ReadString (empty string)'); + Expect( Length(prot.ReadBinary) = 0, 'empty WriteBinary/ReadBinary (empty data block)'); + prot.ReadListEnd; + + // test binary data + Expect( Length(binary) = Length(binRead), 'Binary data length check'); + iErr := -1; + for i := Low(binary) to High(binary) do begin + if binary[i] <> binRead[i] then begin + iErr := i; + Break; + end; + end; + if iErr < 0 + then Expect( TRUE, 'Binary data check ('+IntToStr(Length(binary))+' Bytes)') + else Expect( FALSE, 'Binary data check at offset '+IntToStr(iErr)); + + Expect( stm.Position = stm.Size, 'Stream position after read'); + + + // Solidus can be encoded in two ways. Make sure we can read both + stm.Position := 0; + stm.Size := 0; + stm.WriteString(SOLIDUS_JSON_DATA); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + Expect( prot.ReadString = SOLIDUS_EXCPECTED, 'Solidus encoding'); + + + // Widechars should work too. Do they? + // After writing, we ensure that we are able to read it back + // We can't assume hex-encoding, since (nearly) any Unicode char is valid JSON + stm.Position := 0; + stm.Size := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); + prot.WriteString( G_CLEF_AND_CYRILLIC_TEXT); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + FLogger.Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Writing JSON with chars > 8 bit'); + + // Widechars should work with hex-encoding too. Do they? + stm.Position := 0; + stm.Size := 0; + stm.WriteString( G_CLEF_AND_CYRILLIC_JSON); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + FLogger.Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Reading JSON with chars > 8 bit'); + + + finally + stm.Free; + prot := nil; //-> Release + FLogger.StartTestGroup( '', test_Unknown); // no more tests here + end; +end; + + +procedure TQuickUnitTests.HashSetTest; +var container : IThriftHashSet; + testdata : array of Integer; + i : Integer; +const + TEST_COUNT = 4096; +begin + StartTestGroup( 'IThriftHashSet implementation', test_Containers); + + // prepare test data + SetLength( testdata, 5); + testdata[0] := -2; + testdata[1] := 0; + testdata[2] := 42; + testdata[3] := MaxInt; + testdata[4] := Low(Integer); + + // first insert + container := TThriftHashSetImpl.Create; + for i in testdata do begin + Expect( container.Add( i), 'add first '+IntToStr(i)); + Expect( container.Contains( i), 'contains '+IntToStr(i)); + end; + Expect( container.Count = Length(testdata), 'container size'); + + // insert again + for i in testdata do begin + Expect( not container.Add( i), 'add second '+IntToStr(i)); + Expect( container.Contains( i), 'contains '+IntToStr(i)); + end; + Expect( container.Count = Length(testdata), 'container size'); + + // remove + for i in testdata do begin + Expect( container.Remove( i), 'first remove '+IntToStr(i)); + Expect( not container.Contains( i), 'not contains '+IntToStr(i)); + end; + Expect( container.Count = 0, 'container size'); + + // remove again + for i in testdata do begin + Expect( not container.Remove( i), 'second remove '+IntToStr(i)); + Expect( not container.Contains( i), 'not contains '+IntToStr(i)); + end; + Expect( container.Count = 0, 'container size'); + + // append and clear + for i := 0 to TEST_COUNT-1 do begin + container.Add(-i); + container.Add(+i); + end; + Expect( container.Count = 2*TEST_COUNT-1, 'container size check'); + Expect( not container.Contains( -TEST_COUNT), 'element not contained'); + Expect( not container.Contains( TEST_COUNT), 'element not contained'); + container.Clear; + Expect( container.Count = 0, 'count=0 after clear'); +end; + + + + + + + + +end. diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/testsuite/server/TestServer.pas similarity index 100% rename from lib/delphi/test/TestServer.pas rename to lib/delphi/test/testsuite/server/TestServer.pas diff --git a/lib/delphi/test/TestServerEvents.pas b/lib/delphi/test/testsuite/server/TestServerEvents.pas similarity index 100% rename from lib/delphi/test/TestServerEvents.pas rename to lib/delphi/test/testsuite/server/TestServerEvents.pas diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am index 23ebb778908..4259a1f5a14 100644 --- a/lib/erl/Makefile.am +++ b/lib/erl/Makefile.am @@ -78,6 +78,9 @@ dist-hook: $(RM) -r $(distdir)/test/gen-erl/ $(RM) $(distdir)/$(THRIFT_OMIT_FILE) +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ include \ src \ diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config index c3149b4c088..7f80cfdabad 100644 --- a/lib/erl/rebar.config +++ b/lib/erl/rebar.config @@ -39,7 +39,7 @@ ]}. {plugins, [ - {erlfmt, "1.1.0"} + {erlfmt, "1.5.0"} ]}. {erlfmt, [ diff --git a/lib/erl/src/thrift.app.src b/lib/erl/src/thrift.app.src index 0e25b675592..a99f8477d1f 100644 --- a/lib/erl/src/thrift.app.src +++ b/lib/erl/src/thrift.app.src @@ -21,8 +21,8 @@ % A quick description of the application. {description, "Thrift bindings"}, - % The version of the applicaton - {vsn, "0.20.0"}, + % The version of the applicaton + {vsn, "0.23.0"}, % All modules used by the application. {modules, []}, diff --git a/lib/erl/src/thrift_client.erl b/lib/erl/src/thrift_client.erl index 1c274052e25..f5f4415e59b 100644 --- a/lib/erl/src/thrift_client.erl +++ b/lib/erl/src/thrift_client.erl @@ -31,6 +31,7 @@ seqid :: non_neg_integer() }). -type tclient() :: #tclient{}. +-export_type([tclient/0]). new(Protocol, Service) when is_atom(Service) diff --git a/lib/erl/src/thrift_processor.erl b/lib/erl/src/thrift_processor.erl index e17eadba2fb..8d94e8efb20 100644 --- a/lib/erl/src/thrift_processor.erl +++ b/lib/erl/src/thrift_processor.erl @@ -25,9 +25,9 @@ -include("thrift_protocol.hrl"). -record(thrift_processor, { - handler :: module(), + handler :: module() | thrift_multiplexed_map_wrapper:service_handler_map(), protocol :: term(), - service :: atom() + service :: atom() | thrift_multiplexed_map_wrapper:service_handler_map() }). init({_Server, ProtoGen, Service, Handler}) when is_function(ProtoGen, 0) -> diff --git a/lib/erl/src/thrift_reconnecting_client.erl b/lib/erl/src/thrift_reconnecting_client.erl index c9fe2aa036a..6e99bb83229 100644 --- a/lib/erl/src/thrift_reconnecting_client.erl +++ b/lib/erl/src/thrift_reconnecting_client.erl @@ -41,16 +41,16 @@ ]). -record(state, { - client = nil, - host, - port, - thrift_svc, - thrift_opts, - reconn_min, - reconn_max, - reconn_time = 0, - op_cnt_dict, - op_time_dict + client = nil :: 'nil' | thrift_client:tclient(), + host :: inet:socket_address() | inet:hostname(), + port :: inet:port_number(), + thrift_svc :: atom(), + thrift_opts :: list(), + reconn_min :: integer(), + reconn_max :: integer(), + reconn_time = 0 :: integer(), + op_cnt_dict :: dict:dict(), + op_time_dict :: dict:dict() }). %%==================================================================== diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am index 18b6b75f46e..3bfefbc2209 100644 --- a/lib/go/Makefile.am +++ b/lib/go/Makefile.am @@ -48,6 +48,9 @@ clean-local: all-local: $(GO) build $(GOBUILDEXTRA) ./thrift +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ thrift \ coding_standards.md \ diff --git a/lib/go/test/ClientMiddlewareExceptionTest.thrift b/lib/go/test/ClientMiddlewareExceptionTest.thrift index 647c4335939..b48a611fc0a 100644 --- a/lib/go/test/ClientMiddlewareExceptionTest.thrift +++ b/lib/go/test/ClientMiddlewareExceptionTest.thrift @@ -25,11 +25,11 @@ exception Exception2 { // This is a special case, we want to make sure that the middleware don't // accidentally pull result as error. -exception FooResponse { +struct/*exception*/ FooResponse { // returning an exception by any means other than "throws" is illegal } service ClientMiddlewareExceptionTest { - FooResponse foo() throws( + FooResponse foo() throws( // returning an exception by any means other than "throws" is illegal 1: Exception1 error1, 2: Exception2 error2, ) diff --git a/lib/go/test/ForwardType.thrift b/lib/go/test/ForwardType.thrift index 0433c97cfdc..9e3670ef610 100644 --- a/lib/go/test/ForwardType.thrift +++ b/lib/go/test/ForwardType.thrift @@ -25,6 +25,7 @@ struct Struct { 1: optional Exc foo } -exception Exc { +// FIX: Use of "exception" is illegal. An exception is not a normal struct type and cannot be used as such. +struct Exc { 1: optional i32 code } diff --git a/lib/go/test/Makefile.am b/lib/go/test/Makefile.am index 22fad9e42d9..d76f24815dd 100644 --- a/lib/go/test/Makefile.am +++ b/lib/go/test/Makefile.am @@ -62,7 +62,8 @@ gopath: $(THRIFT) $(THRIFTTEST) \ ProcessorMiddlewareTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ValidateTest.thrift \ - ForwardType.thrift + ForwardType.thrift \ + StringParseAllocationTest.thrift mkdir -p gopath/src grep -v list.*map.*list.*map $(THRIFTTEST) | grep -v 'set' > ThriftTest.thrift $(THRIFT) $(THRIFTARGS) -r IncludesTest.thrift @@ -98,6 +99,7 @@ gopath: $(THRIFT) $(THRIFTTEST) \ $(THRIFT) $(THRIFTARGS) ClientMiddlewareExceptionTest.thrift $(THRIFT) $(THRIFTARGS) ValidateTest.thrift $(THRIFT) $(THRIFTARGS) ForwardType.thrift + $(THRIFT) $(THRIFTARGS) StringParseAllocationTest.thrift ln -nfs ../../tests gopath/src/tests cp -r ./dontexportrwtest gopath/src touch gopath @@ -134,6 +136,9 @@ clean-local: client: stubs $(GO) run TestClient.go +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ dontexportrwtest \ tests \ @@ -171,6 +176,7 @@ EXTRA_DIST = \ RefAnnotationFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ + StringParseAllocationTest.thrift \ TypedefFieldTest.thrift \ UnionBinaryTest.thrift \ UnionDefaultValueTest.thrift \ diff --git a/lib/go/test/StringParseAllocationTest.thrift b/lib/go/test/StringParseAllocationTest.thrift new file mode 100644 index 00000000000..0ede9a52be1 --- /dev/null +++ b/lib/go/test/StringParseAllocationTest.thrift @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +struct StringStruct { + 1: required string example +} diff --git a/lib/go/test/UnionBinaryTest.thrift b/lib/go/test/UnionBinaryTest.thrift index f77112bdac6..8bce38d00b3 100644 --- a/lib/go/test/UnionBinaryTest.thrift +++ b/lib/go/test/UnionBinaryTest.thrift @@ -21,5 +21,6 @@ union Sample { 1: map u1, 2: binary u2, - 3: list u3 + 3: list u3, + 4: set u4, } diff --git a/lib/go/test/fuzz/Makefile.am b/lib/go/test/fuzz/Makefile.am index 9677f4f0016..e9a960b5be6 100644 --- a/lib/go/test/fuzz/Makefile.am +++ b/lib/go/test/fuzz/Makefile.am @@ -19,6 +19,7 @@ gopathfuzz: $(THRIFT) fuzz.go $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../tutorial/tutorial.thrift + $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../test/FuzzTest.thrift touch gopathfuzz check: gopathfuzz @@ -27,6 +28,9 @@ check: gopathfuzz clean-local: $(RM) -rf gopathfuzz gen-go +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ fuzz.go \ fuzz_test.go \ diff --git a/lib/go/test/fuzz/README.md b/lib/go/test/fuzz/README.md new file mode 100644 index 00000000000..54bc4ba3809 --- /dev/null +++ b/lib/go/test/fuzz/README.md @@ -0,0 +1,15 @@ +# Go fuzzing README + +To build the fuzz targets, simply run `make check` in this directory + +To reproduce a bug, update the code in the fuzz_test.go file, pass the right input buffer in there and update the code to call the relevant function. + +We currently have the following fuzz targets: + +* FuzzTutorial -- a fuzzer which spins up an mini server and fuzzes it with random data, following the tutorial example +* FuzzParseCompact -- fuzzes the deserialization of the Compact protocol +* FuzzParseBinary -- fuzzes the deserialization of the Binary protocol +* FuzzParseJson -- fuzzes the deserialization of the JSON protocol +* FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol +* FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol +* FuzzRoundtripJson -- fuzzes the roundtrip of the JSON protocol diff --git a/lib/go/test/fuzz/fuzz.go b/lib/go/test/fuzz/fuzz.go index 06983799823..bad6b41349b 100644 --- a/lib/go/test/fuzz/fuzz.go +++ b/lib/go/test/fuzz/fuzz.go @@ -29,11 +29,15 @@ import ( "github.com/apache/thrift/lib/go/test/fuzz/gen-go/shared" "github.com/apache/thrift/lib/go/test/fuzz/gen-go/tutorial" + "github.com/apache/thrift/lib/go/test/fuzz/gen-go/fuzztest" "github.com/apache/thrift/lib/go/thrift" ) const nbFuzzedProtocols = 2 +// 10MB message size limit to prevent over-allocation during fuzzing +const FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024 + func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol { switch d % nbFuzzedProtocols { default: @@ -42,10 +46,12 @@ func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol { return thrift.NewTBinaryProtocolFactoryConf(nil).GetProtocol(t) case 1: return thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(t) + case 2: + return thrift.NewTJSONProtocolFactory().GetProtocol(t) } } -func Fuzz(data []byte) int { +func FuzzTutorial(data []byte) int { if len(data) < 2 { return 0 } @@ -142,3 +148,242 @@ func (p *CalculatorHandler) Zip(ctx context.Context) (err error) { fmt.Print("zip()\n") return nil } + +func FuzzParseBinary(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + // Create transport and protocol + transport := thrift.NewTMemoryBufferLen(len(data)) + defer func() { + transport.Close() + // Reset the buffer to release memory + transport.Buffer.Reset() + }() + transport.Write(data) + config := &thrift.TConfiguration{ + MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, + } + protocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(transport) + + // Try to read the FuzzTest structure + fuzzTest := fuzztest.NewFuzzTest() + err := fuzzTest.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Successfully parsed + return 1 +} + +func FuzzParseCompact(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + // Create transport and protocol + transport := thrift.NewTMemoryBufferLen(len(data)) + defer func() { + transport.Close() + // Reset the buffer to release memory + transport.Buffer.Reset() + }() + transport.Write(data) + config := &thrift.TConfiguration{ + MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, + } + protocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(transport) + + // Try to read the FuzzTest structure + fuzzTest := fuzztest.NewFuzzTest() + err := fuzzTest.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Successfully parsed + return 1 +} + +func FuzzParseJson(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + // Create transport and protocol + transport := thrift.NewTMemoryBufferLen(len(data)) + defer func() { + transport.Close() + // Reset the buffer to release memory + transport.Buffer.Reset() + }() + transport.Write(data) + protocol := thrift.NewTJSONProtocolFactory().GetProtocol(transport) + + // Try to read the FuzzTest structure + fuzzTest := fuzztest.NewFuzzTest() + err := fuzzTest.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Successfully parsed + return 1 +} + +func FuzzRoundtripBinary(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + config := &thrift.TConfiguration{ + MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, + } + + // First parse + transport := thrift.NewTMemoryBufferLen(len(data)) + transport.Write(data) + protocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(transport) + + // Try to read the FuzzTest structure + test1 := fuzztest.NewFuzzTest() + err := test1.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Serialize back + outTransport := thrift.NewTMemoryBuffer() + outProtocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(outTransport) + err = test1.Write(context.Background(), outProtocol) + if err != nil { + return 0 + } + + // Get serialized data and deserialize again + serialized := outTransport.Bytes() + reTransport := thrift.NewTMemoryBufferLen(len(serialized)) + reTransport.Write(serialized) + reProtocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(reTransport) + + test2 := fuzztest.NewFuzzTest() + err = test2.Read(context.Background(), reProtocol) + if err != nil { + return 0 + } + + // Verify equality + if !test1.Equals(test2) { + panic("Roundtrip failed: objects not equal after deserialization") + } + + return 1 +} + +func FuzzRoundtripCompact(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + config := &thrift.TConfiguration{ + MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, + } + + // First parse + transport := thrift.NewTMemoryBufferLen(len(data)) + transport.Write(data) + protocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(transport) + + // Try to read the FuzzTest structure + test1 := fuzztest.NewFuzzTest() + err := test1.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Serialize back + outTransport := thrift.NewTMemoryBuffer() + outProtocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(outTransport) + err = test1.Write(context.Background(), outProtocol) + if err != nil { + return 0 + } + + // Get serialized data and deserialize again + serialized := outTransport.Bytes() + reTransport := thrift.NewTMemoryBufferLen(len(serialized)) + reTransport.Write(serialized) + reProtocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(reTransport) + + test2 := fuzztest.NewFuzzTest() + err = test2.Read(context.Background(), reProtocol) + if err != nil { + return 0 + } + + // Verify equality + if !test1.Equals(test2) { + panic("Roundtrip failed: objects not equal after deserialization") + } + + return 1 +} + +func FuzzRoundtripJson(data []byte) int { + // Skip if input is too small + if len(data) < 1 { + return 0 + } + + // First parse + transport := thrift.NewTMemoryBufferLen(len(data)) + transport.Write(data) + protocol := thrift.NewTJSONProtocolFactory().GetProtocol(transport) + + // Try to read the FuzzTest structure + test1 := fuzztest.NewFuzzTest() + err := test1.Read(context.Background(), protocol) + if err != nil { + // Invalid input, but not a crash + return 0 + } + + // Serialize back + outTransport := thrift.NewTMemoryBuffer() + outProtocol := thrift.NewTJSONProtocolFactory().GetProtocol(outTransport) + err = test1.Write(context.Background(), outProtocol) + if err != nil { + return 0 + } + + // Get serialized data and deserialize again + serialized := outTransport.Bytes() + reTransport := thrift.NewTMemoryBufferLen(len(serialized)) + reTransport.Write(serialized) + reProtocol := thrift.NewTJSONProtocolFactory().GetProtocol(reTransport) + + test2 := fuzztest.NewFuzzTest() + err = test2.Read(context.Background(), reProtocol) + if err != nil { + return 0 + } + + // Verify equality + if !test1.Equals(test2) { + panic("Roundtrip failed: objects not equal after deserialization") + } + + return 1 +} diff --git a/lib/go/test/fuzz/fuzz_test.go b/lib/go/test/fuzz/fuzz_test.go index 2983e0ff3b3..73eb0727156 100644 --- a/lib/go/test/fuzz/fuzz_test.go +++ b/lib/go/test/fuzz/fuzz_test.go @@ -26,5 +26,5 @@ import ( ) func TestFuzz(t *testing.T) { - Fuzz([]byte{1, 2, 3}) + FuzzTutorial([]byte{1, 2, 3}) } diff --git a/lib/go/test/fuzz/go.mod b/lib/go/test/fuzz/go.mod index b7ddd5fcc60..09f660380b2 100644 --- a/lib/go/test/fuzz/go.mod +++ b/lib/go/test/fuzz/go.mod @@ -1,6 +1,6 @@ module github.com/apache/thrift/lib/go/test/fuzz -go 1.21 +go 1.24 require github.com/apache/thrift v0.0.0-00010101000000-000000000000 diff --git a/lib/go/test/go.mod b/lib/go/test/go.mod index 0c032b70fe0..01019187e21 100644 --- a/lib/go/test/go.mod +++ b/lib/go/test/go.mod @@ -1,6 +1,6 @@ module github.com/apache/thrift/lib/go/test -go 1.21 +go 1.24 require ( github.com/apache/thrift v0.0.0-00010101000000-000000000000 diff --git a/lib/go/test/tests/enum_values_test.go b/lib/go/test/tests/enum_values_test.go new file mode 100644 index 00000000000..84bd2657663 --- /dev/null +++ b/lib/go/test/tests/enum_values_test.go @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package tests + +import ( + "slices" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/constoptionalfielda" +) + +func TestEnumValues(t *testing.T) { + want := []constoptionalfielda.Foo{ + constoptionalfielda.Foo_One, + constoptionalfielda.Foo_Two, + } + got := slices.Collect(constoptionalfielda.FooValues()) + t.Logf("FooValues = %#v", got) + if len(got) != len(want) { + t.Fatalf("Want %d values in FooValues(), got %+v", len(want), got) + } + for i, v := range want { + if got[i] != v { + t.Errorf("FooValues()[%d] got %v(%d) want %v(%d)", i, got[i], got[i], v, v) + } + } +} diff --git a/lib/go/test/tests/equals_test.go b/lib/go/test/tests/equals_test.go index b8adc770802..f56d0cb56ec 100644 --- a/lib/go/test/tests/equals_test.go +++ b/lib/go/test/tests/equals_test.go @@ -255,7 +255,7 @@ func genMapFoo() *equalstest.MapEqualsFoo { func genInt64Slice(length int) []int64 { ret := make([]int64, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = int64(length - i) } return ret @@ -263,7 +263,7 @@ func genInt64Slice(length int) []int64 { func genStringSlice(length int) []string { ret := make([]string, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = strconv.Itoa(length - i) } return ret @@ -271,7 +271,7 @@ func genStringSlice(length int) []string { func genBytesSlice(length int) [][]byte { ret := make([][]byte, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = []byte(strconv.Itoa(length - i)) } return ret @@ -279,7 +279,7 @@ func genBytesSlice(length int) [][]byte { func genInt64StringMap(length int) map[int64]string { ret := make(map[int64]string, length) - for i := 0; i < length; i++ { + for i := range length { ret[int64(i)] = strconv.Itoa(i) } return ret diff --git a/lib/go/test/tests/header_zlib_test.go b/lib/go/test/tests/header_zlib_test.go new file mode 100644 index 00000000000..cf2f849358a --- /dev/null +++ b/lib/go/test/tests/header_zlib_test.go @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package tests + +import ( + "context" + "errors" + "io" + "net" + "sync/atomic" + "testing" + "time" + + "github.com/apache/thrift/lib/go/test/gopath/src/servicestest" + "github.com/apache/thrift/lib/go/thrift" +) + +type zlibTestHandler struct { + servicestest.AServ + + tb testing.TB + text string +} + +func (z zlibTestHandler) Stringfunc_1int_1s(ctx context.Context, i int64, s string) (string, error) { + if s != z.text { + z.tb.Errorf("string arg got %q want %q", s, z.text) + } + return z.text, nil +} + +type countingProxy struct { + // Need to fill when constructing + tb testing.TB + remoteAddr net.Addr + + // internal states + listener net.Listener + clientWritten atomic.Int64 + serverWritten atomic.Int64 +} + +func (cp *countingProxy) getAndResetCounters() (req, resp int64) { + req = cp.clientWritten.Swap(0) + resp = cp.serverWritten.Swap(0) + return req, resp +} + +func (cp *countingProxy) serve() { + cp.tb.Helper() + + listener, err := net.Listen("tcp", ":0") + if err != nil { + cp.tb.Fatalf("Failed to listen proxy: %v", err) + } + go func() { + for { + client, err := listener.Accept() + if err != nil { + if !errors.Is(err, io.EOF) && !errors.Is(err, net.ErrClosed) { + cp.tb.Errorf("proxy accept error: %v", err) + } + return + } + server, err := net.Dial(cp.remoteAddr.Network(), cp.remoteAddr.String()) + if err != nil { + cp.tb.Logf("proxy failed to dial server %v: %v", cp.remoteAddr, err) + } + proxy := func(read, write net.Conn, count *atomic.Int64) { + var buf [1024]byte + for { + n, err := read.Read(buf[:]) + if n > 0 { + count.Add(int64(n)) + if _, err := write.Write(buf[:n]); err != nil { + cp.tb.Errorf("proxy write error: %v", err) + } + } + if err != nil { + if !errors.Is(err, io.EOF) && !errors.Is(err, net.ErrClosed) { + cp.tb.Errorf("proxy read error: %v", err) + } + read.Close() + write.Close() + return + } + } + } + // Read from client + go proxy(client, server, &cp.clientWritten) + // Read from server + go proxy(server, client, &cp.serverWritten) + } + }() + cp.listener = listener +} + +func TestTHeaderZlibClient(t *testing.T) { + // Some text that zlib should be able to compress + const text = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` + + socket, err := thrift.NewTServerSocket(":0") + if err != nil { + t.Fatalf("Failed to create server socket: %v", err) + } + // Call listen to reserve a port and check for any issues early + if err := socket.Listen(); err != nil { + t.Fatalf("Failed to listen server socket: %v", err) + } + server := thrift.NewTSimpleServer4( + servicestest.NewAServProcessor(zlibTestHandler{ + tb: t, + text: text, + }), + socket, + thrift.NewTHeaderTransportFactoryConf(nil, nil), + thrift.NewTHeaderProtocolFactoryConf(nil), + ) + go server.Serve() + // give the server a little time to start serving + time.Sleep(10 * time.Millisecond) + t.Cleanup(func() { + server.Stop() + }) + t.Logf("server running on %v", socket.Addr()) + + proxy := countingProxy{ + tb: t, + remoteAddr: socket.Addr(), + } + proxy.serve() + t.Cleanup(func() { + proxy.listener.Close() + }) + t.Logf("proxy running on %v", proxy.listener.Addr()) + + clientRoundtrip := func(cfg *thrift.TConfiguration) { + t.Helper() + + socket := thrift.NewTSocketConf(proxy.listener.Addr().String(), cfg) + if err := socket.Open(); err != nil { + t.Errorf("failed to open socket: %v", err) + return + } + defer socket.Close() + protoFactory := thrift.NewTHeaderProtocolFactoryConf(cfg) + client := thrift.NewTStandardClient( + protoFactory.GetProtocol(socket), + protoFactory.GetProtocol(socket), + ) + c := servicestest.NewAServClient(client) + got, err := c.Stringfunc_1int_1s(context.Background(), 0, text) + if err != nil { + t.Errorf("Stringfunc_1int_1s call failed: %v", err) + return + } + if got != text { + t.Errorf("Stringfunc_1int_1s got %q want %q", got, text) + } + } + + clientRoundtrip(nil) + nozlibReq, nozlibResp := proxy.getAndResetCounters() + t.Logf("nozlib request size: %d, response size: %d", nozlibReq, nozlibResp) + + clientRoundtrip(&thrift.TConfiguration{ + THeaderTransforms: []thrift.THeaderTransformID{thrift.TransformZlib}, + }) + zlibReq, zlibResp := proxy.getAndResetCounters() + t.Logf("zlib request size: %d, response size: %d", zlibReq, zlibResp) + + if zlibReq >= nozlibReq { + t.Errorf("zlib request size %d >= nozlib request size %d", zlibReq, nozlibReq) + } + if zlibResp >= nozlibResp { + t.Errorf("zlib response size %d >= nozlib response size %d", zlibResp, nozlibResp) + } + + clientRoundtrip(nil) + nozlibReq2, nozlibResp2 := proxy.getAndResetCounters() + t.Logf("nozlib2 request size: %d, response size: %d", nozlibReq, nozlibResp) + + if nozlibReq2 != nozlibReq { + t.Errorf("nozlib request 2 size %d != nozlib request size %d", nozlibReq2, nozlibReq) + } + if nozlibResp2 != nozlibResp { + t.Errorf("nozlib response 2 size %d != nozlib response size %d", nozlibResp2, nozlibResp) + } +} diff --git a/lib/go/test/tests/processor_middleware_test.go b/lib/go/test/tests/processor_middleware_test.go index 1bd911cfe60..aedd93f2279 100644 --- a/lib/go/test/tests/processor_middleware_test.go +++ b/lib/go/test/tests/processor_middleware_test.go @@ -32,9 +32,12 @@ import ( const errorMessage = "foo error" -type serviceImpl struct{} +type serviceImpl struct { + sleepTime time.Duration +} -func (serviceImpl) Ping(_ context.Context) (err error) { +func (s serviceImpl) Ping(_ context.Context) (err error) { + time.Sleep(s.sleepTime) return &processormiddlewaretest.Error{ Foo: thrift.StringPtr(errorMessage), } @@ -67,9 +70,14 @@ func checkError(tb testing.TB, err error) { } func TestProcessorMiddleware(t *testing.T) { - const timeout = time.Second + const ( + sleepTime = 10 * time.Millisecond + timeout = sleepTime / 5 + ) - processor := processormiddlewaretest.NewServiceProcessor(&serviceImpl{}) + processor := processormiddlewaretest.NewServiceProcessor(&serviceImpl{ + sleepTime: sleepTime, + }) serverTransport, err := thrift.NewTServerSocket("127.0.0.1:0") if err != nil { t.Fatalf("Could not find available server port: %v", err) @@ -80,7 +88,9 @@ func TestProcessorMiddleware(t *testing.T) { thrift.NewTHeaderTransportFactoryConf(nil, nil), thrift.NewTHeaderProtocolFactoryConf(nil), ) - defer server.Stop() + t.Cleanup(func() { + server.Stop() + }) var wg sync.WaitGroup wg.Add(1) go func() { @@ -103,6 +113,14 @@ func TestProcessorMiddleware(t *testing.T) { client := processormiddlewaretest.NewServiceClient(thrift.NewTStandardClient(protocol, protocol)) - err = client.Ping(context.Background()) - checkError(t, err) + for label, timeout := range map[string]time.Duration{ + "enough-time": sleepTime * 10, + "not-enough-time": sleepTime / 2, + } { + t.Run(label, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + t.Cleanup(cancel) + client.Ping(ctx) + }) + } } diff --git a/lib/go/test/tests/string_parse_allocation_test.go b/lib/go/test/tests/string_parse_allocation_test.go new file mode 100644 index 00000000000..56163b7d070 --- /dev/null +++ b/lib/go/test/tests/string_parse_allocation_test.go @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package tests + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/stringparseallocationtest" + "github.com/apache/thrift/lib/go/thrift" +) + +func TestSimpleJsonStringParse_Allocations(t *testing.T) { + byteAllocationLimit := 100 * 1024 // 100 KB + res := testing.Benchmark(BenchmarkSimpleJsonStringParse_Allocations) + if res.AllocedBytesPerOp() > int64(byteAllocationLimit) { + t.Errorf("Total memory allocation size too high: %d (> %d)", res.AllocedBytesPerOp(), byteAllocationLimit) + } +} + +func BenchmarkSimpleJsonStringParse_Allocations(b *testing.B) { + b.ReportAllocs() + b.StopTimer() + numEscapedQuotes := 1000 + var sb strings.Builder + for range numEscapedQuotes { + sb.WriteString(`\"`) + } + + testString := fmt.Sprintf(`{"1": {"str": "this is a test with %d of escaped quotes %s"}}`, numEscapedQuotes, sb.String()) + stringStruct := stringparseallocationtest.NewStringStruct() + transport := thrift.NewTMemoryBuffer() + p := thrift.NewTJSONProtocol(transport) + + for range b.N { + transport.Reset() + transport.WriteString(testString) + transport.Flush(context.Background()) + b.StartTimer() + _ = stringStruct.Read(context.Background(), p) + b.StopTimer() + } +} diff --git a/lib/go/test/tests/validate_test.go b/lib/go/test/tests/validate_test.go index 957a8df03c7..52e059ab9d5 100644 --- a/lib/go/test/tests/validate_test.go +++ b/lib/go/test/tests/validate_test.go @@ -107,7 +107,7 @@ func TestBasicValidator(t *testing.T) { } bt = validatetest.NewBasicTest() bt.Map1 = make(map[string]string) - for i := 0; i < 11; i++ { + for i := range 11 { bt.Map1[strconv.Itoa(i)] = strconv.Itoa(i) } if err := bt.Validate(); err == nil { @@ -149,7 +149,7 @@ func TestBasicValidator(t *testing.T) { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() - for i := 0; i < 11; i++ { + for range 11 { bt.Set1 = append(bt.Set1, "0") } if err := bt.Validate(); err == nil { @@ -272,7 +272,7 @@ func TestFieldReference(t *testing.T) { frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 frt.Map0 = make(map[string]string) - for i := 0; i < 9; i++ { + for i := range 9 { frt.Map0[strconv.Itoa(i)] = strconv.Itoa(i) } if err := frt.Validate(); err == nil { @@ -289,7 +289,7 @@ func TestFieldReference(t *testing.T) { } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 - for i := 0; i < 9; i++ { + for range 9 { frt.List0 = append(frt.List0, "0") } if err := frt.Validate(); err == nil { @@ -306,7 +306,7 @@ func TestFieldReference(t *testing.T) { } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 - for i := 0; i < 9; i++ { + for range 9 { frt.Set0 = append(frt.Set0, "0") } if err := frt.Validate(); err == nil { diff --git a/lib/go/test/tests/write_texception_test.go b/lib/go/test/tests/write_texception_test.go new file mode 100644 index 00000000000..3241364f88e --- /dev/null +++ b/lib/go/test/tests/write_texception_test.go @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package tests + +import ( + "context" + "errors" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/unionbinarytest" + "github.com/apache/thrift/lib/go/thrift" +) + +func TestWriteUnionTException(t *testing.T) { + // See https://issues.apache.org/jira/browse/THRIFT-5845 + s := unionbinarytest.NewSample() + proto := thrift.NewTBinaryProtocolConf(thrift.NewTMemoryBuffer(), nil) + err := s.Write(context.Background(), proto) + t.Log(err) + if err == nil { + t.Fatal("Writing empty union did not produce error") + } + var te thrift.TException + if !errors.As(err, &te) { + t.Fatalf("Error from writing empty union is not TException: (%T) %v", err, err) + } + if typ := te.TExceptionType(); typ != thrift.TExceptionTypeProtocol && typ != thrift.TExceptionTypeTransport { + t.Errorf("Got TExceptionType %v, want one of TProtocolException or TTransportException", typ) + } +} + +func TestWriteSetTException(t *testing.T) { + // See https://issues.apache.org/jira/browse/THRIFT-5845 + s := unionbinarytest.NewSample() + s.U4 = []string{ + "foo", + "foo", // duplicate + } + proto := thrift.NewTBinaryProtocolConf(thrift.NewTMemoryBuffer(), nil) + err := s.Write(context.Background(), proto) + t.Log(err) + if err == nil { + t.Fatal("Writing duplicate set did not produce error") + } + var te thrift.TException + if !errors.As(err, &te) { + t.Fatalf("Error from writing duplicate set is not TException: (%T) %v", err, err) + } + if typ := te.TExceptionType(); typ != thrift.TExceptionTypeProtocol && typ != thrift.TExceptionTypeTransport { + t.Errorf("Got TExceptionType %v, want one of TProtocolException or TTransportException", typ) + } +} diff --git a/lib/go/thrift/binary_protocol.go b/lib/go/thrift/binary_protocol.go index eded931346e..3f2843ef966 100644 --- a/lib/go/thrift/binary_protocol.go +++ b/lib/go/thrift/binary_protocol.go @@ -355,7 +355,9 @@ func (p *TBinaryProtocol) ReadMapBegin(ctx context.Context) (kType, vType TType, err = NewTProtocolException(e) return } - err = checkSizeForProtocol(size32, p.cfg) + minElemSize := p.getMinSerializedSize(kType) + p.getMinSerializedSize(vType) + totalMinSize := size32 * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } @@ -379,7 +381,9 @@ func (p *TBinaryProtocol) ReadListBegin(ctx context.Context) (elemType TType, si err = NewTProtocolException(e) return } - err = checkSizeForProtocol(size32, p.cfg) + minElemSize := p.getMinSerializedSize(elemType) + totalMinSize := size32 * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } @@ -404,7 +408,9 @@ func (p *TBinaryProtocol) ReadSetBegin(ctx context.Context) (elemType TType, siz err = NewTProtocolException(e) return } - err = checkSizeForProtocol(size32, p.cfg) + minElemSize := p.getMinSerializedSize(elemType) + totalMinSize := size32 * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } @@ -546,16 +552,59 @@ var ( _ TConfigurationSetter = (*TBinaryProtocol)(nil) ) +// Return the minimum number of bytes a type will consume on the wire +func (p *TBinaryProtocol) getMinSerializedSize(ttype TType) int32 { + switch ttype { + case STOP: + return 1 // T_STOP needs to count itself + case VOID: + return 1 // T_VOID needs to count itsel∂ + case BOOL: + return 1 // sizeof(int8) + case BYTE: + return 1 // sizeof(int8) + case DOUBLE: + return 8 // sizeof(double) + case I16: + return 2 // sizeof(short) + case I32: + return 4 // sizeof(int) + case I64: + return 8 // sizeof(long) + case STRING: + return 4 // string length + case STRUCT: + return 1 // empty struct needs at least 1 byte for the T_STOP + case MAP: + return 4 // element count + case SET: + return 4 // element count + case LIST: + return 4 // element count + case UUID: + return 16 // 16 bytes + default: + return 1 // unknown type + } +} + // This function is shared between TBinaryProtocol and TCompactProtocol. // // It tries to read size bytes from trans, in a way that prevents large -// allocations when size is insanely large (mostly caused by malformed message). +// allocations when size is insanely large (mostly caused by malformed message), +// or smaller than bytes.MinRead. func safeReadBytes(size int32, trans io.Reader) ([]byte, error) { if size < 0 { return nil, nil } - - buf := new(bytes.Buffer) - _, err := io.CopyN(buf, trans, int64(size)) - return buf.Bytes(), err + if size > bytes.MinRead { + // Use bytes.Buffer to prevent allocating size bytes when size is very large + buf := new(bytes.Buffer) + _, err := io.CopyN(buf, trans, int64(size)) + return buf.Bytes(), err + } + // Allocate size bytes + b := make([]byte, size) + n, err := io.ReadFull(trans, b) + return b[:n], err } diff --git a/lib/go/thrift/binary_protocol_test.go b/lib/go/thrift/binary_protocol_test.go index 88bfd26b7ea..6657a99ecac 100644 --- a/lib/go/thrift/binary_protocol_test.go +++ b/lib/go/thrift/binary_protocol_test.go @@ -60,6 +60,11 @@ func TestSafeReadBytes(t *testing.T) { askedSize int32 dataSize int }{ + { + label: "tiny", + askedSize: 8, + dataSize: 8, + }, { label: "normal", askedSize: 100, @@ -81,6 +86,9 @@ func TestSafeReadBytes(t *testing.T) { len(buf), ) } + if c.dataSize < bytes.MinRead && cap(buf) != c.dataSize { + t.Errorf("Expected to allocate %d bytes for read, allocated %d", c.dataSize, cap(buf)) + } if !strings.HasPrefix(safeReadBytesSource, string(buf)) { t.Errorf("Unexpected read data: %q", buf) } @@ -112,7 +120,7 @@ func generateSafeReadBytesBenchmark(askedSize int32, dataSize int) func(b *testi return func(b *testing.B) { data := make([]byte, dataSize) b.ResetTimer() - for i := 0; i < b.N; i++ { + for range b.N { safeReadBytes(askedSize, bytes.NewReader(data)) } } diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go index 18915fee8ad..a5223d38e41 100644 --- a/lib/go/thrift/compact_protocol.go +++ b/lib/go/thrift/compact_protocol.go @@ -486,10 +486,6 @@ func (p *TCompactProtocol) ReadMapBegin(ctx context.Context) (keyType TType, val err = NewTProtocolException(e) return } - err = checkSizeForProtocol(size32, p.cfg) - if err != nil { - return - } size = int(size32) keyAndValueType := byte(STOP) @@ -501,6 +497,13 @@ func (p *TCompactProtocol) ReadMapBegin(ctx context.Context) (keyType TType, val } keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4)) valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf)) + + minElemSize := p.getMinSerializedSize(keyType) + p.getMinSerializedSize(valueType) + totalMinSize := size32 * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) + if err != nil { + return + } return } @@ -524,15 +527,18 @@ func (p *TCompactProtocol) ReadListBegin(ctx context.Context) (elemType TType, s } size = int(size2) } - err = checkSizeForProtocol(int32(size), p.cfg) - if err != nil { - return - } elemType, e := p.getTType(tCompactType(size_and_type)) if e != nil { err = NewTProtocolException(e) return } + + minElemSize := p.getMinSerializedSize(elemType) + totalMinSize := int32(size) * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) + if err != nil { + return + } return } @@ -860,6 +866,42 @@ func (p *TCompactProtocol) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } +// Return the minimum number of bytes a type will consume on the wire +func (p *TCompactProtocol) getMinSerializedSize(ttype TType) int32 { + switch ttype { + case STOP: + return 1 // T_STOP needs to count itself + case VOID: + return 1 // T_VOID needs to count itself + case BOOL: + return 1 // sizeof(int8) + case BYTE: + return 1 // sizeof(int8) + case DOUBLE: + return 8 // uses PutUint64() which always writes 8 bytes + case I16: + return 1 // zigzag + case I32: + return 1 // zigzag + case I64: + return 1 // zigzag + case STRING: + return 1 // string length + case STRUCT: + return 1 // empty struct needs at least 1 byte for the T_STOP + case MAP: + return 1 // element count + case SET: + return 1 // element count + case LIST: + return 1 // element count + case UUID: + return 16 // 16 bytes + default: + return 1 // unknown type + } +} + var ( _ TConfigurationSetter = (*TCompactProtocolFactory)(nil) _ TConfigurationSetter = (*TCompactProtocol)(nil) diff --git a/lib/go/thrift/compact_protocol_test.go b/lib/go/thrift/compact_protocol_test.go index 65f77f2c42d..0d9575992b7 100644 --- a/lib/go/thrift/compact_protocol_test.go +++ b/lib/go/thrift/compact_protocol_test.go @@ -33,9 +33,18 @@ func TestReadWriteCompactProtocol(t *testing.T) { NewTFramedTransport(NewTMemoryBuffer()), } - zlib0, _ := NewTZlibTransport(NewTMemoryBuffer(), 0) - zlib6, _ := NewTZlibTransport(NewTMemoryBuffer(), 6) - zlib9, _ := NewTZlibTransport(NewTFramedTransport(NewTMemoryBuffer()), 9) + newTZlibTransport := func(trans TTransport, level int) *TZlibTransport { + t.Helper() + zlibTrans, err := NewTZlibTransport(trans, level) + if err != nil { + t.Fatalf("NewTZlibTransport returned error: %v", err) + } + return zlibTrans + } + + zlib0 := newTZlibTransport(NewTMemoryBuffer(), 0) + zlib6 := newTZlibTransport(NewTMemoryBuffer(), 6) + zlib9 := newTZlibTransport(NewTFramedTransport(NewTMemoryBuffer()), 9) transports = append(transports, zlib0, zlib6, zlib9) for _, trans := range transports { diff --git a/lib/go/thrift/configuration.go b/lib/go/thrift/configuration.go index de27edd674c..a9565d399df 100644 --- a/lib/go/thrift/configuration.go +++ b/lib/go/thrift/configuration.go @@ -56,47 +56,47 @@ const ( // // For example, say you want to migrate this old code into using TConfiguration: // -// sccket, err := thrift.NewTSocketTimeout("host:port", time.Second, time.Second) -// transFactory := thrift.NewTFramedTransportFactoryMaxLength( -// thrift.NewTTransportFactory(), -// 1024 * 1024 * 256, -// ) -// protoFactory := thrift.NewTBinaryProtocolFactory(true, true) +// socket, err := thrift.NewTSocketTimeout("host:port", time.Second, time.Second) +// transFactory := thrift.NewTFramedTransportFactoryMaxLength( +// thrift.NewTTransportFactory(), +// 1024 * 1024 * 256, +// ) +// protoFactory := thrift.NewTBinaryProtocolFactory(true, true) // // This is the wrong way to do it because in the end the TConfiguration used by // socket and transFactory will be overwritten by the one used by protoFactory // because of TConfiguration propagation: // -// // bad example, DO NOT USE -// sccket := thrift.NewTSocketConf("host:port", &thrift.TConfiguration{ -// ConnectTimeout: time.Second, -// SocketTimeout: time.Second, -// }) -// transFactory := thrift.NewTFramedTransportFactoryConf( -// thrift.NewTTransportFactory(), -// &thrift.TConfiguration{ -// MaxFrameSize: 1024 * 1024 * 256, -// }, -// ) -// protoFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{ -// TBinaryStrictRead: thrift.BoolPtr(true), -// TBinaryStrictWrite: thrift.BoolPtr(true), -// }) +// // bad example, DO NOT USE +// socket := thrift.NewTSocketConf("host:port", &thrift.TConfiguration{ +// ConnectTimeout: time.Second, +// SocketTimeout: time.Second, +// }) +// transFactory := thrift.NewTFramedTransportFactoryConf( +// thrift.NewTTransportFactory(), +// &thrift.TConfiguration{ +// MaxFrameSize: 1024 * 1024 * 256, +// }, +// ) +// protoFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{ +// TBinaryStrictRead: thrift.BoolPtr(true), +// TBinaryStrictWrite: thrift.BoolPtr(true), +// }) // // This is the correct way to do it: // -// conf := &thrift.TConfiguration{ -// ConnectTimeout: time.Second, -// SocketTimeout: time.Second, +// conf := &thrift.TConfiguration{ +// ConnectTimeout: time.Second, +// SocketTimeout: time.Second, // -// MaxFrameSize: 1024 * 1024 * 256, +// MaxFrameSize: 1024 * 1024 * 256, // -// TBinaryStrictRead: thrift.BoolPtr(true), -// TBinaryStrictWrite: thrift.BoolPtr(true), -// } -// sccket := thrift.NewTSocketConf("host:port", conf) -// transFactory := thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), conf) -// protoFactory := thrift.NewTBinaryProtocolFactoryConf(conf) +// TBinaryStrictRead: thrift.BoolPtr(true), +// TBinaryStrictWrite: thrift.BoolPtr(true), +// } +// socket := thrift.NewTSocketConf("host:port", conf) +// transFactory := thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), conf) +// protoFactory := thrift.NewTBinaryProtocolFactoryConf(conf) // // [1]: https://github.com/apache/thrift/blob/master/doc/specs/thrift-tconfiguration.md type TConfiguration struct { @@ -132,6 +132,8 @@ type TConfiguration struct { // THeaderProtocolIDPtr and THeaderProtocolIDPtrMust helper functions // are provided to help filling this value. THeaderProtocolID *THeaderProtocolID + // The write transforms to be applied to THeaderTransport. + THeaderTransforms []THeaderTransformID // Used internally by deprecated constructors, to avoid overriding // underlying TTransport/TProtocol's cfg by accidental propagations. @@ -245,6 +247,18 @@ func (tc *TConfiguration) GetTHeaderProtocolID() THeaderProtocolID { return protoID } +// GetTHeaderTransforms returns the THeaderTransformIDs to be applied on +// THeaderTransport writing. +// +// It's nil-safe. If tc is nil, empty slice will be returned (meaning no +// transforms to be applied). +func (tc *TConfiguration) GetTHeaderTransforms() []THeaderTransformID { + if tc == nil { + return nil + } + return tc.THeaderTransforms +} + // THeaderProtocolIDPtr validates and returns the pointer to id. // // If id is not a valid THeaderProtocolID, a pointer to THeaderProtocolDefault diff --git a/lib/go/thrift/duplicate_protocol.go b/lib/go/thrift/duplicate_protocol.go index 6413909d482..a9eb7eb24e1 100644 --- a/lib/go/thrift/duplicate_protocol.go +++ b/lib/go/thrift/duplicate_protocol.go @@ -198,6 +198,10 @@ func (tdtp *TDuplicateToProtocol) ReadStructEnd(ctx context.Context) (err error) func (tdtp *TDuplicateToProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { name, typeId, id, err = tdtp.Delegate.ReadFieldBegin(ctx) + if typeId == STOP { + tdtp.DuplicateTo.WriteFieldStop(ctx) + return + } tdtp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) return } diff --git a/lib/go/thrift/duplicate_protocol_test.go b/lib/go/thrift/duplicate_protocol_test.go new file mode 100644 index 00000000000..6674f0442c5 --- /dev/null +++ b/lib/go/thrift/duplicate_protocol_test.go @@ -0,0 +1,52 @@ +package thrift + +import ( + "bytes" + "context" + "encoding/json" + "testing" +) + +func TestDuplicateToJSONReadMakesEqualJSON(t *testing.T) { + delegateBuf := NewTMemoryBuffer() + iprot := NewTJSONProtocolFactory().GetProtocol(delegateBuf) + + s := NewMyTestStruct() + ctx := context.Background() + s.Write(ctx, iprot) + + iprot.Flush(ctx) + jsonBytesWritten := delegateBuf.Bytes() + + if err := json.Unmarshal(jsonBytesWritten, NewMyTestStruct()); err != nil { + t.Errorf("error unmarshaling written bytes: %s", err) + } + + duplicateBuf := NewTMemoryBuffer() + dupProto := NewTJSONProtocolFactory().GetProtocol(duplicateBuf) + proto := &TDuplicateToProtocol{ + Delegate: NewTJSONProtocolFactory().GetProtocol(delegateBuf), + DuplicateTo: dupProto, + } + + if err := s.Read(ctx, proto); err != nil { + t.Errorf("error reading struct from DuplicateTo: %s", err) + } + dupProto.Flush(ctx) + + jsonBytesRead := duplicateBuf.Bytes() + + if !bytes.Equal(jsonBytesWritten, jsonBytesRead) { + t.Errorf(`bytes read into duplicate do not equal bytes written + read: + %s + written: + %s + `, jsonBytesRead, jsonBytesWritten) + } + + dup := NewMyTestStruct() + if err := dup.Read(ctx, dupProto); err != nil { + t.Errorf("error reading struct from duplicated protocol: %s", err) + } +} diff --git a/lib/go/thrift/exception.go b/lib/go/thrift/exception.go index e2f1728eac5..5b4cad96faa 100644 --- a/lib/go/thrift/exception.go +++ b/lib/go/thrift/exception.go @@ -121,20 +121,20 @@ var _ TException = wrappedTException{} // // For a endpoint defined in thrift IDL like this: // -// service MyService { -// FooResponse foo(1: FooRequest request) throws ( -// 1: Exception1 error1, -// 2: Exception2 error2, -// ) -// } +// service MyService { +// FooResponse foo(1: FooRequest request) throws ( +// 1: Exception1 error1, +// 2: Exception2 error2, +// ) +// } // // The thrift compiler generated go code for the result TStruct would be like: // -// type MyServiceFooResult struct { -// Success *FooResponse `thrift:"success,0" db:"success" json:"success,omitempty"` -// Error1 *Exception1 `thrift:"error1,1" db:"error1" json:"error1,omitempty"` -// Error2 *Exception2 `thrift:"error2,2" db:"error2" json:"error2,omitempty"` -// } +// type MyServiceFooResult struct { +// Success *FooResponse `thrift:"success,0" db:"success" json:"success,omitempty"` +// Error1 *Exception1 `thrift:"error1,1" db:"error1" json:"error1,omitempty"` +// Error2 *Exception2 `thrift:"error2,2" db:"error2" json:"error2,omitempty"` +// } // // And this function extracts the first non-nil exception out of // *MyServiceFooResult. @@ -144,7 +144,7 @@ func ExtractExceptionFromResult(result TStruct) error { return nil } typ := v.Type() - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { if typ.Field(i).Name == "Success" { continue } diff --git a/lib/go/thrift/framed_transport_test.go b/lib/go/thrift/framed_transport_test.go index d23ec595e6f..e5aa4700cde 100644 --- a/lib/go/thrift/framed_transport_test.go +++ b/lib/go/thrift/framed_transport_test.go @@ -42,7 +42,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { writer := NewTFramedTransport(trans) t.Run("pair", func(t *testing.T) { - for i := 0; i < n; i++ { + for i := range n { // write if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) @@ -64,7 +64,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { t.Run("batched", func(t *testing.T) { // write - for i := 0; i < n; i++ { + for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } @@ -74,7 +74,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { } // read - for i := 0; i < n; i++ { + for i := range n { const ( size = len(content) ) diff --git a/lib/go/thrift/header_protocol.go b/lib/go/thrift/header_protocol.go index 36777b4ca00..bec84b85c49 100644 --- a/lib/go/thrift/header_protocol.go +++ b/lib/go/thrift/header_protocol.go @@ -119,6 +119,11 @@ func (p *THeaderProtocol) ClearWriteHeaders() { } // AddTransform add a transform for writing. +// +// Deprecated: This only applies to the next message written, and the next read +// message will cause write transforms to be reset from what's configured in +// TConfiguration. For sticky transforms, use TConfiguration.THeaderTransforms +// instead. func (p *THeaderProtocol) AddTransform(transform THeaderTransformID) error { return p.transport.AddTransform(transform) } diff --git a/lib/go/thrift/header_protocol_test.go b/lib/go/thrift/header_protocol_test.go index 48a69bf23b0..dfd84f83012 100644 --- a/lib/go/thrift/header_protocol_test.go +++ b/lib/go/thrift/header_protocol_test.go @@ -39,4 +39,24 @@ func TestReadWriteHeaderProtocol(t *testing.T) { })) }, ) + + t.Run( + "binary-zlib", + func(t *testing.T) { + ReadWriteProtocolTest(t, NewTHeaderProtocolFactoryConf(&TConfiguration{ + THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolBinary), + THeaderTransforms: []THeaderTransformID{TransformZlib}, + })) + }, + ) + + t.Run( + "compact-zlib", + func(t *testing.T) { + ReadWriteProtocolTest(t, NewTHeaderProtocolFactoryConf(&TConfiguration{ + THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolCompact), + THeaderTransforms: []THeaderTransformID{TransformZlib}, + })) + }, + ) } diff --git a/lib/go/thrift/header_transport.go b/lib/go/thrift/header_transport.go index 3aea5a9888d..06f71b3a30d 100644 --- a/lib/go/thrift/header_transport.go +++ b/lib/go/thrift/header_transport.go @@ -128,7 +128,7 @@ var _ io.ReadCloser = (*TransformReader)(nil) // // If you don't know the closers capacity beforehand, just use // -// &TransformReader{Reader: baseReader} +// &TransformReader{Reader: baseReader} // // instead would be sufficient. func NewTransformReaderWithCapacity(baseReader io.Reader, capacity int) *TransformReader { @@ -151,6 +151,11 @@ func (tr *TransformReader) Close() error { } // AddTransform adds a transform. +// +// Deprecated: This only applies to the next message written, and the next read +// message will cause write transforms to be reset from what's configured in +// TConfiguration. For sticky transforms, use TConfiguration.THeaderTransforms +// instead. func (tr *TransformReader) AddTransform(id THeaderTransformID) error { switch id { default: @@ -161,7 +166,7 @@ func (tr *TransformReader) AddTransform(id THeaderTransformID) error { case TransformNone: // no-op case TransformZlib: - readCloser, err := zlib.NewReader(tr.Reader) + readCloser, err := newZlibReader(tr.Reader) if err != nil { return err } @@ -217,9 +222,12 @@ func (tw *TransformWriter) AddTransform(id THeaderTransformID) error { case TransformNone: // no-op case TransformZlib: - writeCloser := zlib.NewWriter(tw.Writer) - tw.Writer = writeCloser - tw.closers = append(tw.closers, writeCloser) + writer, closer, err := newZlibWriterCloserLevel(tw.Writer, zlib.DefaultCompression) + if err != nil { + return err + } + tw.Writer = writer + tw.closers = append(tw.closers, closer) } return nil } @@ -300,11 +308,12 @@ func NewTHeaderTransportConf(trans TTransport, conf *TConfiguration) *THeaderTra } PropagateTConfiguration(trans, conf) return &THeaderTransport{ - transport: trans, - reader: bufio.NewReader(trans), - writeHeaders: make(THeaderMap), - protocolID: conf.GetTHeaderProtocolID(), - cfg: conf, + transport: trans, + reader: bufio.NewReader(trans), + writeHeaders: make(THeaderMap), + writeTransforms: conf.GetTHeaderTransforms(), + protocolID: conf.GetTHeaderProtocolID(), + cfg: conf, } } @@ -449,6 +458,11 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e } t.protocolID = THeaderProtocolID(protoID) + // Reset writeTransforms to the ones from cfg, as we are going to add + // compression transforms from what we read, we don't want to accumulate + // different transforms read from different requests + t.writeTransforms = t.cfg.GetTHeaderTransforms() + var transformCount int32 transformCount, err = hp.readVarint32() if err != nil { @@ -461,12 +475,21 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e ) t.frameReader = reader transformIDs := make([]THeaderTransformID, transformCount) - for i := 0; i < int(transformCount); i++ { + for i := range int(transformCount) { id, err := hp.readVarint32() if err != nil { return err } - transformIDs[i] = THeaderTransformID(id) + tID := THeaderTransformID(id) + transformIDs[i] = tID + + // For compression transforms, we should also add them + // to writeTransforms so that the response (assuming we + // are reading a request) would do the same compression. + switch tID { + case TransformZlib: + t.addWriteTransformsDedupe(tID) + } } // The transform IDs on the wire was added based on the order of // writing, so on the reading side we need to reverse the order. @@ -494,7 +517,7 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e if err != nil { return err } - for i := 0; i < int(count); i++ { + for range int(count) { key, err := hp.ReadString(ctx) if err != nil { return err @@ -544,7 +567,7 @@ func (t *THeaderTransport) Read(p []byte) (read int, err error) { // the last Read finished the frame, do endOfFrame // handling here. err = t.endOfFrame() - } else if err == io.EOF { + } else if errors.Is(err, io.EOF) { err = t.endOfFrame() if err != nil { return @@ -726,6 +749,9 @@ func (t *THeaderTransport) ClearWriteHeaders() { } // AddTransform add a transform for writing. +// +// NOTE: This is provided as a low-level API, but in general you should use +// TConfiguration.THeaderTransforms to set transforms for writing instead. func (t *THeaderTransport) AddTransform(transform THeaderTransformID) error { if !supportedTransformIDs[transform] { return NewTProtocolExceptionWithType( @@ -758,6 +784,17 @@ func (t *THeaderTransport) isFramed() bool { } } +// addWriteTransformsDedupe adds id to writeTransforms only if it's not already +// there. +func (t *THeaderTransport) addWriteTransformsDedupe(id THeaderTransformID) { + for _, existingID := range t.writeTransforms { + if existingID == id { + return + } + } + t.writeTransforms = append(t.writeTransforms, id) +} + // SetTConfiguration implements TConfigurationSetter. func (t *THeaderTransport) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(t.transport, cfg) diff --git a/lib/go/thrift/header_transport_test.go b/lib/go/thrift/header_transport_test.go index 125a5fd8c36..09a03313299 100644 --- a/lib/go/thrift/header_transport_test.go +++ b/lib/go/thrift/header_transport_test.go @@ -316,7 +316,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { writer := NewTHeaderTransport(trans) t.Run("pair", func(t *testing.T) { - for i := 0; i < n; i++ { + for i := range n { // write if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) @@ -338,7 +338,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { t.Run("batched", func(t *testing.T) { // write - for i := 0; i < n; i++ { + for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } @@ -348,7 +348,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { } // read - for i := 0; i < n; i++ { + for i := range n { const ( size = len(content) ) diff --git a/lib/go/thrift/json_protocol.go b/lib/go/thrift/json_protocol.go index 6743a7fe3b8..3d53b698d80 100644 --- a/lib/go/thrift/json_protocol.go +++ b/lib/go/thrift/json_protocol.go @@ -314,11 +314,14 @@ func (p *TJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueT if err != nil { return keyType, valueType, size, err } - err = checkSizeForProtocol(int32(iSize), p.cfg) + size = int(iSize) + + minElemSize := p.getMinSerializedSize(keyType) + p.getMinSerializedSize(valueType) + totalMinSize := int32(iSize) * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return keyType, valueType, 0, err } - size = int(iSize) _, e = p.ParseObjectStart() return keyType, valueType, size, e @@ -492,11 +495,14 @@ func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) if err != nil { return elemType, 0, err } - err = checkSizeForProtocol(int32(nSize), p.cfg) + size = int(nSize) + + minElemSize := p.getMinSerializedSize(elemType) + totalMinSize := int32(nSize) * minElemSize + err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return elemType, 0, err } - size = int(nSize) return elemType, size, nil } @@ -564,4 +570,40 @@ func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) } +// Return the minimum number of bytes a type will consume on the wire +func (p *TJSONProtocol) getMinSerializedSize(ttype TType) int32 { + switch ttype { + case STOP: + return 1 // T_STOP needs to count itself + case VOID: + return 1 // T_VOID needs to count itself + case BOOL: + return 1 // written as int + case BYTE: + return 1 + case DOUBLE: + return 1 + case I16: + return 1 + case I32: + return 1 + case I64: + return 1 + case STRING: + return 2 // empty string + case STRUCT: + return 2 // empty struct + case MAP: + return 2 // empty map + case SET: + return 2 // empty set + case LIST: + return 2 // empty list + case UUID: + return 16 // empty UUID + default: + return 1 // unknown type + } +} + var _ TConfigurationSetter = (*TJSONProtocol)(nil) diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go index 39e52d15069..1680532cfbd 100644 --- a/lib/go/thrift/json_protocol_test.go +++ b/lib/go/thrift/json_protocol_test.go @@ -451,7 +451,7 @@ func TestReadJSONProtocolBinary(t *testing.T) { if len(v) != len(value) { t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v)) } - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i]) } diff --git a/lib/go/thrift/lowlevel_benchmarks_test.go b/lib/go/thrift/lowlevel_benchmarks_test.go index e1736557b14..b389388aaad 100644 --- a/lib/go/thrift/lowlevel_benchmarks_test.go +++ b/lib/go/thrift/lowlevel_benchmarks_test.go @@ -41,7 +41,7 @@ func BenchmarkBinaryBool_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -52,7 +52,7 @@ func BenchmarkBinaryByte_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -63,7 +63,7 @@ func BenchmarkBinaryI16_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -74,7 +74,7 @@ func BenchmarkBinaryI32_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -84,7 +84,7 @@ func BenchmarkBinaryI64_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -94,7 +94,7 @@ func BenchmarkBinaryDouble_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -104,7 +104,7 @@ func BenchmarkBinaryString_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -114,7 +114,7 @@ func BenchmarkBinaryBinary_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -125,7 +125,7 @@ func BenchmarkBinaryBool_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -136,7 +136,7 @@ func BenchmarkBinaryByte_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -147,7 +147,7 @@ func BenchmarkBinaryI16_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -158,7 +158,7 @@ func BenchmarkBinaryI32_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -168,7 +168,7 @@ func BenchmarkBinaryI64_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -178,7 +178,7 @@ func BenchmarkBinaryDouble_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -188,7 +188,7 @@ func BenchmarkBinaryString_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -198,7 +198,7 @@ func BenchmarkBinaryBinary_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -209,7 +209,7 @@ func BenchmarkBinaryBool_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -220,7 +220,7 @@ func BenchmarkBinaryByte_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -231,7 +231,7 @@ func BenchmarkBinaryI16_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -242,7 +242,7 @@ func BenchmarkBinaryI32_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -252,7 +252,7 @@ func BenchmarkBinaryI64_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -262,7 +262,7 @@ func BenchmarkBinaryDouble_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -272,7 +272,7 @@ func BenchmarkBinaryString_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -282,7 +282,7 @@ func BenchmarkBinaryBinary_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -293,7 +293,7 @@ func BenchmarkCompactBool_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -304,7 +304,7 @@ func BenchmarkCompactByte_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -315,7 +315,7 @@ func BenchmarkCompactI16_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -326,7 +326,7 @@ func BenchmarkCompactI32_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -336,7 +336,7 @@ func BenchmarkCompactI64_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -346,7 +346,7 @@ func BenchmarkCompactDouble0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -356,7 +356,7 @@ func BenchmarkCompactString0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -366,7 +366,7 @@ func BenchmarkCompactBinary0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -377,7 +377,7 @@ func BenchmarkCompactBool_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -388,7 +388,7 @@ func BenchmarkCompactByte_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -399,7 +399,7 @@ func BenchmarkCompactI16_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -410,7 +410,7 @@ func BenchmarkCompactI32_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -420,7 +420,7 @@ func BenchmarkCompactI64_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -430,7 +430,7 @@ func BenchmarkCompactDouble1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -440,7 +440,7 @@ func BenchmarkCompactString1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -450,7 +450,7 @@ func BenchmarkCompactBinary1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -461,7 +461,7 @@ func BenchmarkCompactBool_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -472,7 +472,7 @@ func BenchmarkCompactByte_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -483,7 +483,7 @@ func BenchmarkCompactI16_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -494,7 +494,7 @@ func BenchmarkCompactI32_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -504,7 +504,7 @@ func BenchmarkCompactI64_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -514,7 +514,7 @@ func BenchmarkCompactDouble2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -524,7 +524,7 @@ func BenchmarkCompactString2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -534,7 +534,7 @@ func BenchmarkCompactBinary2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } diff --git a/lib/go/thrift/pool.go b/lib/go/thrift/pool.go index 1d623d42223..6912f3ea5d5 100644 --- a/lib/go/thrift/pool.go +++ b/lib/go/thrift/pool.go @@ -43,7 +43,7 @@ func newPool[T any](generate func() *T, reset func(*T)) *pool[T] { } return &pool[T]{ pool: sync.Pool{ - New: func() interface{} { + New: func() any { return generate() }, }, diff --git a/lib/go/thrift/processor_factory.go b/lib/go/thrift/processor_factory.go index 245a3ccfc98..64f89141336 100644 --- a/lib/go/thrift/processor_factory.go +++ b/lib/go/thrift/processor_factory.go @@ -19,7 +19,11 @@ package thrift -import "context" +import ( + "context" + "fmt" + "strings" +) // A processor is a generic object which operates upon an input stream and // writes to some output stream. @@ -78,3 +82,49 @@ func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactor func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction { return p.processor } + +// ProcessorError is the combined original error returned by the endpoint +// implementation, and I/O error when writing the response back to the client. +// +// This type will be returned by Process function if there's an error happened +// during writing the response back to the client. ProcessorMiddlewares can +// check for this type (use errors.As) to get the underlying write and endpoint +// errors. +type ProcessorError struct { + // WriteError is the error happened during writing the response to the + // client, always set. + WriteError TException + + // EndpointError is the original error returned by the endpoint + // implementation, might be nil. + EndpointError TException +} + +func (pe *ProcessorError) Unwrap() []error { + if pe.EndpointError != nil { + return []error{ + pe.WriteError, + pe.EndpointError, + } + } + return []error{pe.WriteError} +} + +func (pe *ProcessorError) Error() string { + var sb strings.Builder + sb.WriteString("thrift.ProcessorError: ") + sb.WriteString(fmt.Sprintf("write response to client: %v", pe.WriteError)) + if pe.EndpointError != nil { + sb.WriteString(fmt.Sprintf("; original error from endpoint: %v", pe.EndpointError)) + } + return sb.String() +} + +func (pe *ProcessorError) TExceptionType() TExceptionType { + return pe.WriteError.TExceptionType() +} + +var ( + _ error = (*ProcessorError)(nil) + _ TException = (*ProcessorError)(nil) +) diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go index 2ee14caaad1..68cfe4aaa25 100644 --- a/lib/go/thrift/protocol.go +++ b/lib/go/thrift/protocol.go @@ -146,7 +146,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, keyType, maxDepth-1) if err != nil { return err @@ -163,7 +163,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err @@ -175,7 +175,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err diff --git a/lib/go/thrift/protocol_test.go b/lib/go/thrift/protocol_test.go index 1093c94a969..4fac8013502 100644 --- a/lib/go/thrift/protocol_test.go +++ b/lib/go/thrift/protocol_test.go @@ -45,7 +45,7 @@ var ( func init() { protocol_bdata = make([]byte, PROTOCOL_BINARY_DATA_SIZE) - for i := 0; i < PROTOCOL_BINARY_DATA_SIZE; i++ { + for i := range PROTOCOL_BINARY_DATA_SIZE { protocol_bdata[i] = byte((i + 'a') % 255) } BOOL_VALUES = []bool{false, true, false, false, true} @@ -531,7 +531,7 @@ func ReadWriteBinary(t testing.TB, p TProtocol, trans TTransport) { if len(v) != len(value) { t.Errorf("%s: %T %T len(v) != len(value)... %d != %d", "ReadWriteBinary", p, trans, len(v), len(value)) } else { - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Errorf("%s: %T %T %s != %s", "ReadWriteBinary", p, trans, v, value) } diff --git a/lib/go/thrift/serializer_test.go b/lib/go/thrift/serializer_test.go index 425ce0691bc..19879c582d5 100644 --- a/lib/go/thrift/serializer_test.go +++ b/lib/go/thrift/serializer_test.go @@ -328,7 +328,7 @@ func BenchmarkSerializer(b *testing.B) { b.Run( c.Label, func(b *testing.B) { - for i := 0; i < b.N; i++ { + for range b.N { s := c.Serializer() m := MyTestStruct{} str, _ := s.WriteString(context.Background(), &m) diff --git a/lib/go/thrift/serializer_types_test.go b/lib/go/thrift/serializer_types_test.go index 4d1e992ae42..d96001636f6 100644 --- a/lib/go/thrift/serializer_types_test.go +++ b/lib/go/thrift/serializer_types_test.go @@ -319,7 +319,7 @@ func (p *MyTestStruct) readField9(ctx context.Context, iprot TProtocol) error { } tMap := make(map[string]string, size) p.StringMap = tMap - for i := 0; i < size; i++ { + for range size { var _key0 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) @@ -347,7 +347,7 @@ func (p *MyTestStruct) readField10(ctx context.Context, iprot TProtocol) error { } tSlice := make([]string, 0, size) p.StringList = tSlice - for i := 0; i < size; i++ { + for range size { var _elem2 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) @@ -369,7 +369,7 @@ func (p *MyTestStruct) readField11(ctx context.Context, iprot TProtocol) error { } tSet := make(map[string]struct{}, size) p.StringSet = tSet - for i := 0; i < size; i++ { + for range size { var _elem3 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) diff --git a/lib/go/thrift/server_socket.go b/lib/go/thrift/server_socket.go index 7dd24ae3648..164221e92b2 100644 --- a/lib/go/thrift/server_socket.go +++ b/lib/go/thrift/server_socket.go @@ -26,12 +26,12 @@ import ( ) type TServerSocket struct { - listener net.Listener addr net.Addr clientTimeout time.Duration - // Protects the interrupted value to make it thread safe. + // Protects the listener and interrupted fields to make them thread safe. mu sync.RWMutex + listener net.Listener interrupted bool } @@ -69,15 +69,13 @@ func (p *TServerSocket) Listen() error { func (p *TServerSocket) Accept() (TTransport, error) { p.mu.RLock() interrupted := p.interrupted + listener := p.listener p.mu.RUnlock() if interrupted { return nil, errTransportInterrupted } - p.mu.Lock() - listener := p.listener - p.mu.Unlock() if listener == nil { return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") } @@ -110,7 +108,9 @@ func (p *TServerSocket) Open() error { } func (p *TServerSocket) Addr() net.Addr { - if p.listener != nil { + p.mu.RLock() + defer p.mu.RUnlock() + if p.IsListening() { return p.listener.Addr() } return p.addr diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index 8b1284fd1b1..ec12991a1d7 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -30,6 +30,7 @@ import ( "io" "math" "strconv" + "strings" ) type _ParseContext int @@ -922,15 +923,7 @@ func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { if err != nil { return "", NewTProtocolException(err) } - l := len(line) - // count number of escapes to see if we need to keep going - i := 1 - for ; i < l; i++ { - if line[l-i-1] != '\\' { - break - } - } - if i&0x01 == 1 { + if endsWithoutEscapedQuote(line) { v, ok := jsonUnquote(string(JSON_QUOTE) + line) if !ok { return "", NewTProtocolException(err) @@ -951,27 +944,29 @@ func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { } func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) { - line, err := p.reader.ReadString(JSON_QUOTE) - if err != nil { - return "", NewTProtocolException(err) + var sb strings.Builder + + for { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + sb.WriteString(line) + if endsWithoutEscapedQuote(line) { + return sb.String(), nil + } } - l := len(line) - // count number of escapes to see if we need to keep going +} + +func endsWithoutEscapedQuote(s string) bool { + l := len(s) i := 1 for ; i < l; i++ { - if line[l-i-1] != '\\' { + if s[l-i-1] != '\\' { break } } - if i&0x01 == 1 { - return line, nil - } - s, err := p.ParseQuotedStringBody() - if err != nil { - return "", NewTProtocolException(err) - } - v := line + s - return v, nil + return i&0x01 == 1 } func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) { @@ -1200,7 +1195,7 @@ func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { for continueFor { c, err := p.reader.ReadByte() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return NUMERIC_NULL, NewTProtocolException(err) @@ -1311,7 +1306,7 @@ func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { // Safely peeks into the buffer, reading only what is necessary func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool { - for i := 0; i < len(b); i++ { + for i := range b { a, _ := p.reader.Peek(i + 1) if len(a) < (i+1) || a[i] != b[i] { return false diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index 89753c6148a..002a2310333 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -497,7 +497,7 @@ func TestReadSimpleJSONProtocolBinary(t *testing.T) { if len(v) != len(value) { t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v)) } - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i]) } diff --git a/lib/go/thrift/simple_server.go b/lib/go/thrift/simple_server.go index a8634fc5f0e..58973753723 100644 --- a/lib/go/thrift/simple_server.go +++ b/lib/go/thrift/simple_server.go @@ -24,7 +24,6 @@ import ( "errors" "io" "log/slog" - "net" "sync" "sync/atomic" "time" @@ -205,12 +204,14 @@ func (p *TSimpleServer) innerAccept() (int32, error) { return 0, err } if client != nil { + ctx, cancel := context.WithCancel(context.Background()) p.wg.Add(2) go func() { defer p.wg.Done() defer cancel() + defer client.Close() if err := p.processRequests(client); err != nil { ctx := p.logContext.Load() slog.ErrorContext(*ctx, "error processing request", "err", err) @@ -366,13 +367,7 @@ func (p *TSimpleServer) processRequests(client TTransport) (err error) { ok, err := processor.Process(ctx, inputProtocol, outputProtocol) if errors.Is(err, ErrAbandonRequest) { - err := client.Close() - if errors.Is(err, net.ErrClosed) { - // In this case, it's kinda expected to get - // net.ErrClosed, treat that as no-error - return nil - } - return err + return nil } if errors.As(err, new(TTransportException)) && err != nil { return err diff --git a/lib/go/thrift/simple_server_test.go b/lib/go/thrift/simple_server_test.go index f3a59ee18ea..0fcb01bd8b8 100644 --- a/lib/go/thrift/simple_server_test.go +++ b/lib/go/thrift/simple_server_test.go @@ -294,6 +294,7 @@ func TestErrAbandonRequest(t *testing.T) { if !errors.Is(ErrAbandonRequest, context.Canceled) { t.Error("errors.Is(ErrAbandonRequest, context.Canceled) returned false") } + //lint:ignore SA1032 Intentional order for this test. if errors.Is(context.Canceled, ErrAbandonRequest) { t.Error("errors.Is(context.Canceled, ErrAbandonRequest) returned true") } diff --git a/lib/go/thrift/socket_aix_syscall.go b/lib/go/thrift/socket_aix_syscall.go new file mode 100644 index 00000000000..2253f753188 --- /dev/null +++ b/lib/go/thrift/socket_aix_syscall.go @@ -0,0 +1,29 @@ +//go:build aix +// +build aix + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package thrift + +import "syscall" + +func peekNonblocking(fd int, p []byte) (int, syscall.Sockaddr, error) { + return syscall.Recvfrom(fd, p, syscall.MSG_PEEK|syscall.MSG_NONBLOCK) +} diff --git a/lib/go/thrift/socket_non_aix_syscall.go b/lib/go/thrift/socket_non_aix_syscall.go new file mode 100644 index 00000000000..523f356dba3 --- /dev/null +++ b/lib/go/thrift/socket_non_aix_syscall.go @@ -0,0 +1,29 @@ +//go:build !aix && !windows && !wasm +// +build !aix,!windows,!wasm + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package thrift + +import "syscall" + +func peekNonblocking(fd int, p []byte) (int, syscall.Sockaddr, error) { + return syscall.Recvfrom(fd, p, syscall.MSG_PEEK|syscall.MSG_DONTWAIT) +} diff --git a/lib/go/thrift/socket_unix_conn.go b/lib/go/thrift/socket_unix_conn.go index ac0dce9e8d2..c06e0e1f6ec 100644 --- a/lib/go/thrift/socket_unix_conn.go +++ b/lib/go/thrift/socket_unix_conn.go @@ -58,7 +58,7 @@ func (sc *socketConn) checkConn() error { var n int if readErr := rc.Read(func(fd uintptr) bool { - n, _, err = syscall.Recvfrom(int(fd), sc.buffer[:], syscall.MSG_PEEK|syscall.MSG_DONTWAIT) + n, _, err = peekNonblocking(int(fd), sc.buffer[:]) return true }); readErr != nil { return readErr diff --git a/lib/go/thrift/ssl_server_socket.go b/lib/go/thrift/ssl_server_socket.go index 907afca326f..3f05ad93db6 100644 --- a/lib/go/thrift/ssl_server_socket.go +++ b/lib/go/thrift/ssl_server_socket.go @@ -93,6 +93,9 @@ func (p *TSSLServerSocket) Open() error { } func (p *TSSLServerSocket) Addr() net.Addr { + if p.listener != nil { + return p.listener.Addr() + } return p.addr } diff --git a/lib/go/thrift/transport_test.go b/lib/go/thrift/transport_test.go index 309cc280507..b6263b8b577 100644 --- a/lib/go/thrift/transport_test.go +++ b/lib/go/thrift/transport_test.go @@ -36,7 +36,7 @@ var ( func init() { transport_bdata = make([]byte, TRANSPORT_BINARY_DATA_SIZE) - for i := 0; i < TRANSPORT_BINARY_DATA_SIZE; i++ { + for i := range TRANSPORT_BINARY_DATA_SIZE { transport_bdata[i] = byte((i + 'a') % 255) } transport_header = map[string]string{"key": "User-Agent", diff --git a/lib/go/thrift/zlib_pool.go b/lib/go/thrift/zlib_pool.go new file mode 100644 index 00000000000..b41929167bb --- /dev/null +++ b/lib/go/thrift/zlib_pool.go @@ -0,0 +1,109 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. + */ + +package thrift + +import ( + "compress/zlib" + "io" + "sync" +) + +type zlibReader interface { + io.ReadCloser + zlib.Resetter +} + +var zlibReaderPool sync.Pool + +func newZlibReader(r io.Reader) (io.ReadCloser, error) { + if reader, _ := zlibReaderPool.Get().(*wrappedZlibReader); reader != nil { + if err := reader.Reset(r, nil); err == nil { + return reader, nil + } + } + reader, err := zlib.NewReader(r) + if err != nil { + return nil, err + } + return &wrappedZlibReader{reader.(zlibReader)}, nil +} + +type wrappedZlibReader struct { + zlibReader +} + +func (wr *wrappedZlibReader) Close() error { + defer func() { + zlibReaderPool.Put(wr) + }() + return wr.zlibReader.Close() +} + +func newZlibWriterLevelMust(level int) *zlib.Writer { + w, err := zlib.NewWriterLevel(nil, level) + if err != nil { + panic(err) + } + return w +} + +// level -> pool +var zlibWriterPools map[int]*pool[zlib.Writer] = func() map[int]*pool[zlib.Writer] { + m := make(map[int]*pool[zlib.Writer]) + for level := zlib.HuffmanOnly; level <= zlib.BestCompression; level++ { + // force a panic at init if we have an invalid level here + newZlibWriterLevelMust(level) + m[level] = newPool( + func() *zlib.Writer { + return newZlibWriterLevelMust(level) + }, + nil, + ) + } + return m +}() + +type zlibWriterPoolCloser struct { + writer *zlib.Writer + pool *pool[zlib.Writer] +} + +func (z *zlibWriterPoolCloser) Close() error { + defer func() { + z.writer.Reset(nil) + z.pool.put(&z.writer) + }() + return z.writer.Close() +} + +func newZlibWriterCloserLevel(w io.Writer, level int) (*zlib.Writer, io.Closer, error) { + pool, ok := zlibWriterPools[level] + if !ok { + // not pooled + writer, err := zlib.NewWriterLevel(w, level) + if err != nil { + return nil, nil, err + } + return writer, writer, nil + } + writer := pool.get() + writer.Reset(w) + return writer, &zlibWriterPoolCloser{writer: writer, pool: pool}, nil +} diff --git a/lib/go/thrift/zlib_pool_test.go b/lib/go/thrift/zlib_pool_test.go new file mode 100644 index 00000000000..1b3f5d8afe7 --- /dev/null +++ b/lib/go/thrift/zlib_pool_test.go @@ -0,0 +1,51 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. + */ + +package thrift + +import ( + "compress/zlib" + "fmt" + "maps" + "slices" + "testing" +) + +func TestZlibWriterPools(t *testing.T) { + // make sure we have the writer pools created at the given levels + for _, level := range []int{ + zlib.HuffmanOnly, + zlib.DefaultCompression, + zlib.NoCompression, + zlib.BestSpeed, + zlib.BestCompression, + } { + t.Run(fmt.Sprintf("%d", level), func(t *testing.T) { + _, ok := zlibWriterPools[level] + if !ok { + t.Errorf("level %d does not exist in the writer pools", level) + } + }) + } + if t.Failed() { + levels := slices.Collect(maps.Keys(zlibWriterPools)) + slices.Sort(levels) + t.Log("zlib writer pools:", levels) + } +} diff --git a/lib/go/thrift/zlib_transport.go b/lib/go/thrift/zlib_transport.go index cefe1f99448..8f2d073b53e 100644 --- a/lib/go/thrift/zlib_transport.go +++ b/lib/go/thrift/zlib_transport.go @@ -33,9 +33,10 @@ type TZlibTransportFactory struct { // TZlibTransport is a TTransport implementation that makes use of zlib compression. type TZlibTransport struct { - reader io.ReadCloser - transport TTransport - writer *zlib.Writer + reader io.ReadCloser + transport TTransport + writer *zlib.Writer + writeCloser io.Closer } // GetTransport constructs a new instance of NewTZlibTransport @@ -64,14 +65,14 @@ func NewTZlibTransportFactoryWithFactory(level int, factory TTransportFactory) * // NewTZlibTransport constructs a new instance of TZlibTransport func NewTZlibTransport(trans TTransport, level int) (*TZlibTransport, error) { - w, err := zlib.NewWriterLevel(trans, level) + writer, closer, err := newZlibWriterCloserLevel(trans, level) if err != nil { return nil, err } - return &TZlibTransport{ - writer: w, - transport: trans, + writer: writer, + writeCloser: closer, + transport: trans, }, nil } @@ -83,7 +84,7 @@ func (z *TZlibTransport) Close() error { return err } } - if err := z.writer.Close(); err != nil { + if err := z.writeCloser.Close(); err != nil { return err } return z.transport.Close() @@ -109,7 +110,7 @@ func (z *TZlibTransport) Open() error { func (z *TZlibTransport) Read(p []byte) (int, error) { if z.reader == nil { - r, err := zlib.NewReader(z.transport) + r, err := newZlibReader(z.transport) if err != nil { return 0, NewTTransportExceptionFromError(err) } diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json index 78779da4534..87af3424249 100644 --- a/lib/haxe/haxelib.json +++ b/lib/haxe/haxelib.json @@ -10,7 +10,7 @@ "framework" ], "description": "Haxe bindings for the Apache Thrift RPC and serialization framework", - "version": "0.20.0", + "version": "0.23.0", "releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.", "contributors": ["ApacheThrift"], "dependencies": { diff --git a/lib/haxe/src/org/apache/thrift/TConfiguration.hx b/lib/haxe/src/org/apache/thrift/TConfiguration.hx index 47973f2c2c0..3bc5a864f8c 100644 --- a/lib/haxe/src/org/apache/thrift/TConfiguration.hx +++ b/lib/haxe/src/org/apache/thrift/TConfiguration.hx @@ -25,9 +25,9 @@ class TConfiguration public static inline var DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries public static inline var DEFAULT_RECURSION_DEPTH = 64; - public var MaxMessageSize(default,null) : Int = DEFAULT_MAX_MESSAGE_SIZE; - public var MaxFrameSize(default,null) : Int = DEFAULT_MAX_FRAME_SIZE; - public var RecursionLimit(default,null) : Int = DEFAULT_RECURSION_DEPTH; + public var MaxMessageSize(default,default) : Int = DEFAULT_MAX_MESSAGE_SIZE; + public var MaxFrameSize(default,default) : Int = DEFAULT_MAX_FRAME_SIZE; + public var RecursionLimit(default,default) : Int = DEFAULT_RECURSION_DEPTH; // TODO(JensG): add connection and i/o timeouts diff --git a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx index 48b8d1e5cf3..c510895de00 100644 --- a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx +++ b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx @@ -321,8 +321,8 @@ class TBinaryProtocol extends TProtocolImplBase implements TProtocol { { switch (type) { - case TType.STOP: return 0; - case TType.VOID_: return 0; + case TType.STOP: return 1; // T_STOP needs to count itself + case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; case TType.BYTE: return 1; case TType.DOUBLE: return 8; @@ -330,7 +330,7 @@ class TBinaryProtocol extends TProtocolImplBase implements TProtocol { case TType.I32: return 4; case TType.I64: return 8; case TType.STRING: return 4; // string length - case TType.STRUCT: return 0; // empty struct + case TType.STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.MAP: return 4; // element count case TType.SET: return 4; // element count case TType.LIST: return 4; // element count diff --git a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx index d3577f1f770..22af9e8024e 100644 --- a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx +++ b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx @@ -725,8 +725,8 @@ class TCompactProtocol extends TProtocolImplBase implements TProtocol { { switch (type) { - case TType.STOP: return 0; - case TType.VOID_: return 0; + case TType.STOP: return 1; // T_STOP needs to count itself + case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; case TType.DOUBLE: return 8; // uses fixedLongToBytes() which always writes 8 bytes case TType.BYTE: return 1; @@ -734,7 +734,7 @@ class TCompactProtocol extends TProtocolImplBase implements TProtocol { case TType.I32: return 1; // zigzag case TType.I64: return 1; // zigzag case TType.STRING: return 1; // string length - case TType.STRUCT: return 0; // empty struct + case TType.STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.MAP: return 1; // element count case TType.SET: return 1; // element count case TType.LIST: return 1; // element count diff --git a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx index a47479d42a2..4bbc42725a6 100644 --- a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx +++ b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx @@ -792,8 +792,8 @@ class TJSONProtocol extends TProtocolImplBase implements TProtocol { { switch (type) { - case TType.STOP: return 0; - case TType.VOID_: return 0; + case TType.STOP: return 1; // T_STOP needs to count itself + case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; // written as int case TType.BYTE: return 1; case TType.DOUBLE: return 1; diff --git a/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx index b20dc702dc3..fad3b549245 100644 --- a/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx +++ b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx @@ -78,7 +78,7 @@ class TEndpointTransport extends TTransport // Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data public override function CheckReadBytesAvailable(numBytes : Int64) : Void { - if (RemainingMessageSize < numBytes) + if (RemainingMessageSize < numBytes || numBytes < 0) throw new TTransportException(TTransportException.END_OF_FILE, 'CheckReadBytesAvailable(${numBytes}): MaxMessageSize reached, only ${RemainingMessageSize} bytes available'); } diff --git a/lib/haxe/src/org/apache/thrift/transport/TMemoryStream.hx b/lib/haxe/src/org/apache/thrift/transport/TMemoryStream.hx new file mode 100644 index 00000000000..49b494e64d2 --- /dev/null +++ b/lib/haxe/src/org/apache/thrift/transport/TMemoryStream.hx @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.thrift.transport; + +import haxe.io.Bytes; +import haxe.io.BytesBuffer; +import haxe.io.Output; + +class TMemoryStream implements TStream { + + private var Data : Bytes; + public var Position(default,default) : Int; + + public function new( data : Bytes = null) { + var target = new BytesBuffer(); + if ( data != null) { + for ( i in 0...data.length) { + target.addByte( data.get(i)); + ++Position; + } + } + Data = target.getBytes(); + } + + private function IsEof() : Bool { + return (0 > Position) || (Position >= Data.length); + } + + public function Close() : Void { + var target = new BytesBuffer(); + Data = target.getBytes(); + Position = 0; + } + + public function Peek() : Bool { + return (! IsEof()); + } + + // read count bytes into buf starting at offset + public function Read( buf : Bytes, offset : Int, count : Int) : Int { + var numRead = 0; + + for ( i in 0...count) { + if ( IsEof()) + break; + + buf.set( offset + i, Data.get( Position++)); + ++numRead; + } + + return numRead; + } + + // write count bytes from buf starting at offset + public function Write( buf : Bytes, offset : Int, count : Int) : Void { + var numBytes = buf.length - offset; + if ( numBytes > count) { + numBytes = count; + } + + for ( i in 0...numBytes) { + Data.set( Position + i, buf.get( offset + i)); + } + } + + public function Flush() : Void { + // nothing to do + } + +} + diff --git a/lib/haxe/test/HaxeTests.hxproj b/lib/haxe/test/HaxeTests.hxproj index 839917b4757..fbb9c8e5ef0 100644 --- a/lib/haxe/test/HaxeTests.hxproj +++ b/lib/haxe/test/HaxeTests.hxproj @@ -63,7 +63,7 @@ thrift -r -gen haxe ../../../lib/rb/benchmark/Benchmark.thrift