Skip to content

Add assume_64_bit_php codegen option to the PHP generator#27013

Open
sergiosalvatore wants to merge 1 commit into
protocolbuffers:mainfrom
sergiosalvatore:php-64-bit-only
Open

Add assume_64_bit_php codegen option to the PHP generator#27013
sergiosalvatore wants to merge 1 commit into
protocolbuffers:mainfrom
sergiosalvatore:php-64-bit-only

Conversation

@sergiosalvatore
Copy link
Copy Markdown

@sergiosalvatore sergiosalvatore commented Apr 21, 2026

Generated PHP code currently type-hints 64-bit integer fields as
int|string to cover 32-bit PHP builds, where values that overflow a
native int are returned as strings. On 64-bit PHP — the mainstream
deployment — the runtime always returns native int, so the union is
dead weight that noisies up static analysis, IDE autocompletion, and
docs for everyone who has committed to 64-bit.

This change adds an opt-in CLI option, analogous to aggregate_metadata:

protoc --php_out=assume_64_bit_php:. foo.proto

When the flag is present, INT64/UINT64/SINT64/FIXED64/SFIXED64 fields
emit int instead of int|string across setter signatures, PHPDoc
@param / @return / @type, and RepeatedField<...> generics
(which naturally collapse from RepeatedField<int>|RepeatedField<string>
to RepeatedField<int>). Wrapper types (Int64Value, UInt64Value)
honor the flag via Options threaded into the wrapper doc-comment
helpers. Default behavior (flag absent) is unchanged.

Scope:

  • Codegen only. Runtime libraries (GPBUtil.php, convert.c) already
    return native int on 64-bit PHP regardless of this flag.
  • No change to checked-in generated WKT .php files; they remain on
    default behavior unless regenerated with the flag.
  • No new .proto file-level option.
  • Descriptor-mode generation (is_descriptor=true) is intentionally
    unchanged.

Unit tests cover the flag-on and flag-absent paths, scalar and repeated
64-bit fields, and verify the int|string union is fully absent when
the flag is enabled.

@sergiosalvatore sergiosalvatore requested a review from a team as a code owner April 21, 2026 20:54
@sergiosalvatore sergiosalvatore requested review from zhangskz and removed request for a team April 21, 2026 20:54
@google-cla
Copy link
Copy Markdown

google-cla Bot commented Apr 21, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@loci-dev
Copy link
Copy Markdown

LOCI found performance insights on your pull request.

🔎 Check latest report here.

@zhangskz zhangskz requested review from bshaffer and removed request for zhangskz April 22, 2026 14:49
Copy link
Copy Markdown
Contributor

@bshaffer bshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool feature! This is LGTM from my side, but I have a few questions for core protobuf before accepting:

  • Can you confirm that this feature is idiomatic with other protoc feature flags?
  • Would it be possible to just drop support for 32-bit PHP builds? I don't know how important this is to continue to support, but it would certainly make our lives easier and our codebases cleaner to drop it.

Generated PHP code currently type-hints 64-bit integer fields as
`int|string` to cover 32-bit PHP builds, where values that overflow a
native `int` are returned as strings. On 64-bit PHP — the mainstream
deployment — the runtime always returns native `int`, so the union is
dead weight that noisies up static analysis, IDE autocompletion, and
docs for everyone who has committed to 64-bit.

This change adds an opt-in CLI option, analogous to `aggregate_metadata`:

    protoc --php_out=assume_64_bit_php:. foo.proto

When the flag is present, INT64/UINT64/SINT64/FIXED64/SFIXED64 fields
emit `int` instead of `int|string` across setter signatures, PHPDoc
`@param` / `@return` / `@type`, and `RepeatedField<...>` generics
(which naturally collapse from `RepeatedField<int>|RepeatedField<string>`
to `RepeatedField<int>`). Wrapper types (`Int64Value`, `UInt64Value`)
honor the flag via `Options` threaded into the wrapper doc-comment
helpers. Default behavior (flag absent) is unchanged.

Scope:

- Codegen only. Runtime libraries (GPBUtil.php, convert.c) already
  return native `int` on 64-bit PHP regardless of this flag.
- No change to checked-in generated WKT .php files; they remain on
  default behavior unless regenerated with the flag.
- No new .proto file-level option.
- Descriptor-mode generation (`is_descriptor=true`) is intentionally
  unchanged.

Unit tests cover the flag-on and flag-absent paths, scalar and repeated
64-bit fields, and verify the `int|string` union is fully absent when
the flag is enabled.
@sergiosalvatore sergiosalvatore changed the title Add php_64_bit_only codegen option to the PHP generator Add assume_64_bit_php codegen option to the PHP generator Apr 22, 2026
@sergiosalvatore
Copy link
Copy Markdown
Author

Thanks for the reply @bshaffer! You make an excellent point about the naming. In light of that, I've changed the flag to assume_64_bit_php to be consistent with the other flags like aggregate_metadata (verb first, and without the php prefix). Having php at the end made sense to me given that I'm trying to be explicit that it's the architecture of PHP in particular that's important. I'm happy to hear any alternatives or suggestions you might have. Also, apparently the convention (at least within the php renderer) is as a bare flag without a value which simplifies some things.

With regard to dropping support for 32-bit PHP builds, that would be completely fine with me. However, I'm unsure of what the general strategy for such changes are within protobuf in general. My $0.02 might be to introduce it as a flag so folks like me can make use of it now, and indicate that 32-bit support (and the flag) will be removed in a future release. Again, I yield to any suggestions you might have.

@rgoldfinger6 rgoldfinger6 added the 🅰️ safe for tests Mark a commit as safe to run presubmits over label May 18, 2026
@github-actions github-actions Bot removed the 🅰️ safe for tests Mark a commit as safe to run presubmits over label May 18, 2026
@rgoldfinger6 rgoldfinger6 requested a review from haberman May 18, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants