THRIFT-6041: Add js:bigint compiler flag for native BigInt int64 codegen#3529
Open
jimexist wants to merge 1 commit into
Open
THRIFT-6041: Add js:bigint compiler flag for native BigInt int64 codegen#3529jimexist wants to merge 1 commit into
jimexist wants to merge 1 commit into
Conversation
8afbcad to
a359296
Compare
a359296 to
b201658
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the Thrift JS (node) generator to emit native bigint for i64 by default via a new js:bigint flag (default true), and adds runtime helper APIs (thrift.toBigInt, thrift.fromBigInt) to bridge between node-int64 Int64 and bigint at generated read/write sites.
Changes:
- Add
js:bigintgenerator option (defaulttrueforjs:node, forcedfalsefor plainjs) and adjust JS/TS codegen to usebigint+ helper wrappers. - Export
toBigInt/fromBigInthelpers from the Node and browser entrypoints, and add new unit tests covering helper behavior and bigint-mode codegen. - Pin existing node/nodets integration fixtures to
bigint=falseto preserve legacynode-int64-based assertions.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/nodets/test/testAll.sh | Pins js:node,ts test fixtures to bigint=false for legacy semantics. |
| lib/nodejs/test/testAll.sh | Pins existing fixtures to bigint=false, adds a separate bigint-mode generated fixture and runs new bigint tests. |
| lib/nodejs/test/int64_bigint.test.js | New test asserting bigint-mode codegen output (constants, no node-int64 import). |
| lib/nodejs/test/bigint_helpers.test.js | New test suite validating helper conversions + protocol round-trips. |
| lib/nodejs/README.md | Updates stated Node compatibility and documents js:bigint behavior and helpers. |
| lib/nodejs/lib/thrift/index.js | Adds thrift.toBigInt / thrift.fromBigInt exports (needs compatibility fallback). |
| lib/nodejs/lib/thrift/browser.js | Adds thrift.toBigInt / thrift.fromBigInt exports for browser bundle (needs compatibility fallback). |
| lib/nodejs/lib/thrift/binary_protocol.js | Minor formatting change (trailing comma) in an exception constructor call. |
| compiler/cpp/src/thrift/generate/t_js_generator.cc | Implements js:bigint flag, adjusts includes, const rendering, (de)serialization wrapping, and TS typing for i64. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b201658 to
1a04bda
Compare
Client: nodejs,compiler
Adds BigInt support to the js:node binding entirely through the
compiler and JS-level helpers; the binary protocol itself is not
touched.
### Compiler — `js:bigint` flag (default `true`)
t_js_generator.cc gains a `bigint` flag that applies when `node` is in
the option list. When enabled (the default):
- I64 constants are emitted as native BigInt literals (e.g. `42n`,
`9223372036854775807n`) instead of `new Int64(42)`.
- The node-int64 import is dropped from `js_includes`, `ts_includes`,
and `ts_service_includes` (node + esm + ts variants).
- TypeScript I64 fields are declared as `bigint` instead of `Int64`.
- Read sites are wrapped: `this.field = thrift.toBigInt(input.readI64())`.
- Write sites are wrapped: `output.writeI64(thrift.fromBigInt(this.field))`.
Pass `bigint=false` to retain the legacy node-int64 codegen. The flag
is silently forced to false for plain `--gen js` (browser JS).
### Runtime — two JS-level helpers, no protocol changes
`lib/nodejs/lib/thrift/index.js` (and browser.js) export:
- `thrift.toBigInt(i64) -> bigint` — reads the underlying buffer with
`readBigInt64BE`, honoring the Int64's offset.
- `thrift.fromBigInt(value) -> Int64` — packs a bigint into an 8-byte
buffer with `writeBigInt64BE`, wrapping out-of-range values via
`BigInt.asIntN(64, ...)`.
`TBinaryProtocol` is unchanged. The conversion boundary lives in
generated code (and any user code that wants to opt in), keeping the
protocol code paths simple.
### Test coverage
- `lib/nodejs/test/bigint_helpers.test.js` (new) — 32 assertions:
round-trip the helpers across the full signed 64-bit range, verify
the protocol round-trip via the helpers, check offset handling, and
check `BigInt.asIntN(64, ...)` wrapping on overflow. Passes locally.
- `lib/nodejs/test/int64_bigint.test.js` (new) — validates the
compiler emits BigInt literals, drops `require('node-int64')`, and
drops `new Int64(...)` from generated output. Runs against a
separate `gen-nodejs-bigint/` fixture in CI.
- All existing test generation invocations in
`lib/nodejs/test/testAll.sh` and `lib/nodets/test/testAll.sh` now
pass `bigint=false` explicitly, so `int64.test.js`, `int64.test.ts`,
`test_driver.mjs`, and `test-cases.mjs` keep working with their
existing node-int64 semantics without rewrites.
Also fixes the stale "node version 6 or later" claim in the nodejs
README that contradicted the `engines` field.
No JIRA ticket has been filed for this work yet; a committer should
create one (suggested summary: "Add BigInt support to the js:node
generator via a default-true bigint flag") and the PR title / branch
name can then be updated to match the THRIFT-NNNN convention.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Generated-by: Claude Opus 4.7
1a04bda to
92e9f3e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The js generator now emits native
BigIntfori64by default. A new compiler flagjs:bigint(defaulttrue) controls the behavior, and a pair of JS-level helpers (thrift.toBigInt,thrift.fromBigInt) bridge between the wire format andbigintat the codegen site.TBinaryProtocolitself is unchanged.Node 10.4+ has supported
BigIntfor years and the published package already targets Node ≥ 10.18 viaengines, so every supported runtime can use it.Compiler —
js:bigint(defaulttrue)When
nodeis in the option list andbigint=true(the default), the generator:42n/9223372036854775807nBigInt literals for I64 consts instead ofnew Int64(42).node-int64import fromjs_includes,ts_includes, andts_service_includes.bigintinstead ofInt64.this.field = thrift.toBigInt(input.readI64()).output.writeI64(thrift.fromBigInt(this.field)).The flag is silently forced
falsefor plain--gen js(browser JS), so callers that don't enablenodeare unaffected.Runtime — two helpers, no protocol changes
lib/nodejs/lib/thrift/index.js(andbrowser.js) export:thrift.toBigInt(i64) → bigint— reads viaBuffer#readBigInt64BE, honoring the Int64's offset.thrift.fromBigInt(value) → Int64— packs viaBuffer#writeBigInt64BE, wrapping out-of-range values withBigInt.asIntN(64, ...).TBinaryProtocolis untouched.readI64still returns aThrift.Int64,writeI64still expects one. Existing code that usesThrift.Int64directly keeps working.Tests
lib/nodejs/test/bigint_helpers.test.js(new, 32 assertions, passes locally) — round-trips the helpers across the full signed 64-bit range, verifies protocol round-trip via the helpers, checks non-zeroInt64.offsethandling, and checksBigInt.asIntN(64, ...)wrapping on overflow.lib/nodejs/test/int64_bigint.test.js(new) — generatesInt64Test.thriftwith the defaultbigint=trueand asserts the output uses BigInt literals, has norequire('node-int64'), and has nonew Int64(...). Runs against a separategen-nodejs-bigint/fixture in CI.lib/nodejs/test/testAll.shandlib/nodets/test/testAll.share pinned tobigint=false, soint64.test.js,int64.test.ts,test_driver.mjs, andtest-cases.mjskeep working with their existingnode-int64semantics — no rewrites.Also fixes the stale "node version 6 or later" claim in
lib/nodejs/README.mdthat contradicted theenginesfield.JIRA
No JIRA ticket filed yet — a committer should create one (suggested summary: "Add BigInt support to the js:node generator via a default-true bigint flag") and rename the PR title / branch to the
THRIFT-NNNN:convention perAGENTS.md.AI authorship
Per
AGENTS.md§ "AI-Generated Contributions", drafted with Claude Opus 4.7; the human author reviewed and ran the runtime tests. The compiler-side test relies on CI to rebuild the generator binary.Test plan
node lib/nodejs/test/bigint_helpers.test.js— 32/32 pass locallylib/nodejs/test/testAll.shgreen in CI (integration suite +int64.test.js+int64_bigint.test.js)lib/nodets/test/testAll.shgreen in CI