You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c9493dc
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: README.md
+21-5Lines changed: 21 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ For this reason, we have written this plugin, which — in addition to addressin
20
20
-[repeated](#repeated)
21
21
-[maps](#maps)
22
22
-[oneof](#oneof)
23
-
-[precedence](#precedence)
23
+
-[presence](#presence)
24
24
-[grpc client](#grpc-client)
25
25
-[grpc server](#grpc-server)
26
26
-[autoload.metadata.php](#autoloadmetadataphp)
@@ -366,10 +366,26 @@ final readonly class ContactPhone implements \Thesis\Api\Request\Contact
366
366
367
367
#### presence
368
368
369
-
By default, all fields with scalar data types will have corresponding default values (0 for numbers, false for booleans, and so on).
370
-
If proto2 is used and the field is marked as `optional`, scalar types will become nullable, with null as the default value.
371
-
The same applies to `optional` in proto3. Lists and maps, however, will always be non-nullable (especially since they cannot be `required` or `optional`) but will have empty default values.
372
-
Meanwhile, all objects will always be nullable, regardless of `required`/`optional` labels, which allows the serializer to quickly skip such fields and avoid writing unnecessary data.
369
+
The plugin resolves effective field presence from syntax/edition features and generates constructor signatures accordingly.
370
+
For editions, inherited features are resolved through `file` -> `message` -> `field`.
371
+
372
+
The generator decides nullable/default/required for each field using these rules:
373
+
374
+
1. A field is generated as required constructor argument (no default) when either:
2.`repeated` fields are always non-nullable and always default to `[]`.
378
+
3.`map` fields are always non-nullable and default to `new \Thesis\Protobuf\Map()`.
379
+
4.`oneof` container property is always nullable (`?T = null`), because "no active variant" is valid.
380
+
5. Scalar fields with explicit presence (for example `optional` in proto2/proto3, or editions `EXPLICIT`) are nullable and default to `null`.
381
+
6. Scalar fields with implicit presence are non-nullable and use protobuf zero defaults.
382
+
7. Enum fields:
383
+
- without explicit field default: use enum zero/first case default for non-nullable fields;
384
+
- with explicit proto default (`[default = ...]`): generated as non-nullable with that enum case as PHP default;
385
+
- nullable enum fields default to `null`.
386
+
8. Message/object fields are nullable by default and default to `null`; if such field is required (rule 1), it becomes a required constructor argument.
387
+
388
+
For nullable fields, proto-defined defaults are intentionally not baked into constructor defaults, so "unset" can be distinguished from "set to proto default".
0 commit comments