From 9cd1824ac24830d083924c7dc502906ec8cc8a72 Mon Sep 17 00:00:00 2001 From: Julien Chaffraix Date: Mon, 22 Apr 2024 02:51:38 -0700 Subject: [PATCH] Implement support for proto3 optional proto3 optional requires opting into the experimental feature in our code generator. proto3 optional is implemented as a one-off synthetic field so we must treat those as normal objects in our codegenerator. You can find the instructions on how to handle those in the upstream protobuf documentation: https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md The PR adds tests for the logic for both binary and JSON decoding. We are missing reflection support but that seemed reasonable for now. --- BUILD | 2 +- gen.sh | 5 +- .../conformance/conformance_proto.php | 12 +- generated/google/protobuf/api_proto.php | 12 +- .../google/protobuf/compiler/plugin_proto.php | 24 +- .../google/protobuf/descriptor_proto.php | 120 ++-- generated/google/protobuf/struct_proto.php | 10 +- .../protobuf/test_messages_proto2_proto.php | 108 ++-- .../protobuf/test_messages_proto3_proto.php | 250 +++++--- generated/google/protobuf/type_proto.php | 36 +- generated/test/custom_optional_proto3.pb.bin | 3 + generated/test/default_optional_proto3.pb.bin | Bin 0 -> 23 bytes generated/test/empty_optional_proto3.pb.bin | 0 generated/test/example1_proto.php | 60 +- generated/test/example2_proto.php | 12 +- generated/test/example3_proto.php | 24 +- generated/test/example4_proto.php | 12 +- generated/test/exampleany_proto.php | 12 +- .../optional_proto3_file_descriptor.pb.bin.gz | Bin 0 -> 333 bytes generated/test/optional_proto3_proto.php | 535 ++++++++++++++++++ protoc-gen-hack/plugin.go | 137 ++++- test/custom_optional_proto3.pb.txt | 15 + test/default_optional_proto3.pb.txt | 13 + test/empty_optional_proto3.pb.txt | 0 test/mixed_optional_proto3.pb.json | 13 + test/optional_proto3.proto | 29 + test/test.php | 4 + test/test_suite.php | 100 ++++ 28 files changed, 1305 insertions(+), 243 deletions(-) create mode 100644 generated/test/custom_optional_proto3.pb.bin create mode 100644 generated/test/default_optional_proto3.pb.bin create mode 100644 generated/test/empty_optional_proto3.pb.bin create mode 100644 generated/test/optional_proto3_file_descriptor.pb.bin.gz create mode 100644 generated/test/optional_proto3_proto.php create mode 100644 test/custom_optional_proto3.pb.txt create mode 100644 test/default_optional_proto3.pb.txt create mode 100644 test/empty_optional_proto3.pb.txt create mode 100644 test/mixed_optional_proto3.pb.json create mode 100644 test/optional_proto3.proto diff --git a/BUILD b/BUILD index 395d29d..46dafb9 100644 --- a/BUILD +++ b/BUILD @@ -89,7 +89,7 @@ hh_test( hh_args = "lib_test/test.php", ) -INTEGRATION_PHP = glob(["test/**/*.php"]) +INTEGRATION_PHP = glob(["test/**/*.php", "test/**/*.pb.json"]) ALL_PHP += INTEGRATION_PHP diff --git a/gen.sh b/gen.sh index d055ca0..b52363a 100755 --- a/gen.sh +++ b/gen.sh @@ -38,12 +38,15 @@ for SRC in $PBS do echo source: $SRC ARGS="-I external/com_google_protobuf/src -I ./" - $PROTOC $ARGS --plugin=$GENHACK --hack_out="plugin=grpc,allow_proto2_dangerous:$TMP" $SRC + $PROTOC $ARGS --plugin=$GENHACK --hack_out="plugin=grpc,allow_proto2_dangerous:$TMP" --experimental_allow_proto3_optional $SRC echo done ARGS="-I external/com_google_protobuf/src -I ./" $PROTOC $ARGS --encode=foo.bar.example1 ./test/example1.proto < ./test/example1.pb.txt > $TMP/test/example1.pb.bin +$PROTOC $ARGS --encode=baz.optional_proto3 ./test/optional_proto3.proto < ./test/empty_optional_proto3.pb.txt > $TMP/test/empty_optional_proto3.pb.bin +$PROTOC $ARGS --encode=baz.optional_proto3 ./test/optional_proto3.proto < ./test/default_optional_proto3.pb.txt > $TMP/test/default_optional_proto3.pb.bin +$PROTOC $ARGS --encode=baz.optional_proto3 ./test/optional_proto3.proto < ./test/custom_optional_proto3.pb.txt > $TMP/test/custom_optional_proto3.pb.bin if [ $# -gt 0 ]; then # Comparison mode; see if there are diffs, if none, exit 0. diff --git a/generated/external/com_google_protobuf/conformance/conformance_proto.php b/generated/external/com_google_protobuf/conformance/conformance_proto.php index 73de351..ca59276 100644 --- a/generated/external/com_google_protobuf/conformance/conformance_proto.php +++ b/generated/external/com_google_protobuf/conformance/conformance_proto.php @@ -321,7 +321,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->test_category = \conformance\TestCategory::FromInt($d->readVarint()); break; case 6: - if ($this->jspb_encoding_options == null) $this->jspb_encoding_options = new \conformance\JspbEncodingConfig(); + if ($this->jspb_encoding_options is null) { + $this->jspb_encoding_options = new \conformance\JspbEncodingConfig(); + } $this->jspb_encoding_options->MergeFrom($d->readDecoder()); break; case 7: @@ -397,8 +399,10 @@ public function MergeJsonFrom(mixed $m): void { $this->test_category = \conformance\TestCategory::FromMixed($v); break; case 'jspb_encoding_options': case 'jspbEncodingOptions': - if ($v === null) break; - if ($this->jspb_encoding_options == null) $this->jspb_encoding_options = new \conformance\JspbEncodingConfig(); + if ($v is null) break; + if ($this->jspb_encoding_options is null) { + $this->jspb_encoding_options = new \conformance\JspbEncodingConfig(); + } $this->jspb_encoding_options->MergeJsonFrom($v); break; case 'jspb_payload': case 'jspbPayload': @@ -424,7 +428,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->message_type = $o->message_type; $this->test_category = $o->test_category; $tmp = $o->jspb_encoding_options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \conformance\JspbEncodingConfig(); $nv->CopyFrom($tmp); $this->jspb_encoding_options = $nv; diff --git a/generated/google/protobuf/api_proto.php b/generated/google/protobuf/api_proto.php index 818cdc9..9a409c9 100644 --- a/generated/google/protobuf/api_proto.php +++ b/generated/google/protobuf/api_proto.php @@ -67,7 +67,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->version = $d->readString(); break; case 5: - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeFrom($d->readDecoder()); break; case 6: @@ -158,8 +160,10 @@ public function MergeJsonFrom(mixed $m): void { $this->version = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'source_context': case 'sourceContext': - if ($v === null) break; - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($v is null) break; + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeJsonFrom($v); break; case 'mixins': @@ -195,7 +199,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->version = $o->version; $tmp = $o->source_context; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\SourceContext(); $nv->CopyFrom($tmp); $this->source_context = $nv; diff --git a/generated/google/protobuf/compiler/plugin_proto.php b/generated/google/protobuf/compiler/plugin_proto.php index cd434ff..13afe2d 100644 --- a/generated/google/protobuf/compiler/plugin_proto.php +++ b/generated/google/protobuf/compiler/plugin_proto.php @@ -167,7 +167,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->parameter = $d->readString(); break; case 3: - if ($this->compiler_version == null) $this->compiler_version = new \google\protobuf\compiler\Version(); + if ($this->compiler_version is null) { + $this->compiler_version = new \google\protobuf\compiler\Version(); + } $this->compiler_version->MergeFrom($d->readDecoder()); break; case 15: @@ -226,8 +228,10 @@ public function MergeJsonFrom(mixed $m): void { $this->parameter = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'compiler_version': case 'compilerVersion': - if ($v === null) break; - if ($this->compiler_version == null) $this->compiler_version = new \google\protobuf\compiler\Version(); + if ($v is null) break; + if ($this->compiler_version is null) { + $this->compiler_version = new \google\protobuf\compiler\Version(); + } $this->compiler_version->MergeJsonFrom($v); break; case 'proto_file': case 'protoFile': @@ -250,7 +254,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->file_to_generate = $o->file_to_generate; $this->parameter = $o->parameter; $tmp = $o->compiler_version; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\compiler\Version(); $nv->CopyFrom($tmp); $this->compiler_version = $nv; @@ -337,7 +341,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->content = $d->readString(); break; case 16: - if ($this->generated_code_info == null) $this->generated_code_info = new \google\protobuf\GeneratedCodeInfo(); + if ($this->generated_code_info is null) { + $this->generated_code_info = new \google\protobuf\GeneratedCodeInfo(); + } $this->generated_code_info->MergeFrom($d->readDecoder()); break; default: @@ -391,8 +397,10 @@ public function MergeJsonFrom(mixed $m): void { $this->content = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'generated_code_info': case 'generatedCodeInfo': - if ($v === null) break; - if ($this->generated_code_info == null) $this->generated_code_info = new \google\protobuf\GeneratedCodeInfo(); + if ($v is null) break; + if ($this->generated_code_info is null) { + $this->generated_code_info = new \google\protobuf\GeneratedCodeInfo(); + } $this->generated_code_info->MergeJsonFrom($v); break; default: @@ -409,7 +417,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->insertion_point = $o->insertion_point; $this->content = $o->content; $tmp = $o->generated_code_info; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\GeneratedCodeInfo(); $nv->CopyFrom($tmp); $this->generated_code_info = $nv; diff --git a/generated/google/protobuf/descriptor_proto.php b/generated/google/protobuf/descriptor_proto.php index d52f043..f279904 100644 --- a/generated/google/protobuf/descriptor_proto.php +++ b/generated/google/protobuf/descriptor_proto.php @@ -180,11 +180,15 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->extension []= $obj; break; case 8: - if ($this->options == null) $this->options = new \google\protobuf\FileOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\FileOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; case 9: - if ($this->source_code_info == null) $this->source_code_info = new \google\protobuf\SourceCodeInfo(); + if ($this->source_code_info is null) { + $this->source_code_info = new \google\protobuf\SourceCodeInfo(); + } $this->source_code_info->MergeFrom($d->readDecoder()); break; case 10: @@ -337,13 +341,17 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\FileOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\FileOptions(); + } $this->options->MergeJsonFrom($v); break; case 'source_code_info': case 'sourceCodeInfo': - if ($v === null) break; - if ($this->source_code_info == null) $this->source_code_info = new \google\protobuf\SourceCodeInfo(); + if ($v is null) break; + if ($this->source_code_info is null) { + $this->source_code_info = new \google\protobuf\SourceCodeInfo(); + } $this->source_code_info->MergeJsonFrom($v); break; case 'public_dependency': case 'publicDependency': @@ -393,13 +401,13 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->extension []= $nv; } $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\FileOptions(); $nv->CopyFrom($tmp); $this->options = $nv; } $tmp = $o->source_code_info; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\SourceCodeInfo(); $nv->CopyFrom($tmp); $this->source_code_info = $nv; @@ -453,7 +461,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->end = $d->readVarint32Signed(); break; case 3: - if ($this->options == null) $this->options = new \google\protobuf\ExtensionRangeOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\ExtensionRangeOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; default: @@ -499,8 +509,10 @@ public function MergeJsonFrom(mixed $m): void { $this->end = \Protobuf\Internal\JsonDecoder::readInt32Signed($v); break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\ExtensionRangeOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\ExtensionRangeOptions(); + } $this->options->MergeJsonFrom($v); break; default: @@ -516,7 +528,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->start = $o->start; $this->end = $o->end; $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\ExtensionRangeOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -699,7 +711,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->extension []= $obj; break; case 7: - if ($this->options == null) $this->options = new \google\protobuf\MessageOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\MessageOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; case 8: @@ -832,8 +846,10 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\MessageOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\MessageOptions(); + } $this->options->MergeJsonFrom($v); break; case 'oneof_decl': case 'oneofDecl': @@ -892,7 +908,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->extension []= $nv; } $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\MessageOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1179,7 +1195,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->default_value = $d->readString(); break; case 8: - if ($this->options == null) $this->options = new \google\protobuf\FieldOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\FieldOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; case 9: @@ -1289,8 +1307,10 @@ public function MergeJsonFrom(mixed $m): void { $this->default_value = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\FieldOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\FieldOptions(); + } $this->options->MergeJsonFrom($v); break; case 'oneof_index': case 'oneofIndex': @@ -1320,7 +1340,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->type_name = $o->type_name; $this->default_value = $o->default_value; $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\FieldOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1368,7 +1388,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->name = $d->readString(); break; case 2: - if ($this->options == null) $this->options = new \google\protobuf\OneofOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\OneofOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; default: @@ -1406,8 +1428,10 @@ public function MergeJsonFrom(mixed $m): void { $this->name = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\OneofOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\OneofOptions(); + } $this->options->MergeJsonFrom($v); break; default: @@ -1422,7 +1446,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->name = $o->name; $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\OneofOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1570,7 +1594,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->value []= $obj; break; case 3: - if ($this->options == null) $this->options = new \google\protobuf\EnumOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\EnumOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; case 4: @@ -1640,8 +1666,10 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\EnumOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\EnumOptions(); + } $this->options->MergeJsonFrom($v); break; case 'reserved_range': case 'reservedRange': @@ -1673,7 +1701,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->value []= $nv; } $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\EnumOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1730,7 +1758,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->number = $d->readVarint32Signed(); break; case 3: - if ($this->options == null) $this->options = new \google\protobuf\EnumValueOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\EnumValueOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; default: @@ -1776,8 +1806,10 @@ public function MergeJsonFrom(mixed $m): void { $this->number = \Protobuf\Internal\JsonDecoder::readInt32Signed($v); break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\EnumValueOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\EnumValueOptions(); + } $this->options->MergeJsonFrom($v); break; default: @@ -1793,7 +1825,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->name = $o->name; $this->number = $o->number; $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\EnumValueOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1846,7 +1878,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->method []= $obj; break; case 3: - if ($this->options == null) $this->options = new \google\protobuf\ServiceOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\ServiceOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; default: @@ -1897,8 +1931,10 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\ServiceOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\ServiceOptions(); + } $this->options->MergeJsonFrom($v); break; default: @@ -1918,7 +1954,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->method []= $nv; } $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\ServiceOptions(); $nv->CopyFrom($tmp); $this->options = $nv; @@ -1981,7 +2017,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->output_type = $d->readString(); break; case 4: - if ($this->options == null) $this->options = new \google\protobuf\MethodOptions(); + if ($this->options is null) { + $this->options = new \google\protobuf\MethodOptions(); + } $this->options->MergeFrom($d->readDecoder()); break; case 5: @@ -2051,8 +2089,10 @@ public function MergeJsonFrom(mixed $m): void { $this->output_type = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'options': - if ($v === null) break; - if ($this->options == null) $this->options = new \google\protobuf\MethodOptions(); + if ($v is null) break; + if ($this->options is null) { + $this->options = new \google\protobuf\MethodOptions(); + } $this->options->MergeJsonFrom($v); break; case 'client_streaming': case 'clientStreaming': @@ -2075,7 +2115,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->input_type = $o->input_type; $this->output_type = $o->output_type; $tmp = $o->options; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\MethodOptions(); $nv->CopyFrom($tmp); $this->options = $nv; diff --git a/generated/google/protobuf/struct_proto.php b/generated/google/protobuf/struct_proto.php index 722f3c3..f0618ca 100644 --- a/generated/google/protobuf/struct_proto.php +++ b/generated/google/protobuf/struct_proto.php @@ -61,7 +61,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \google\protobuf\Value(); + if ($this->value is null) { + $this->value = new \google\protobuf\Value(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -99,7 +101,9 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($this->value == null) $this->value = new \google\protobuf\Value(); + if ($this->value is null) { + $this->value = new \google\protobuf\Value(); + } $this->value->MergeJsonFrom($v); break; default: @@ -114,7 +118,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Value(); $nv->CopyFrom($tmp); $this->value = $nv; diff --git a/generated/google/protobuf/test_messages_proto2_proto.php b/generated/google/protobuf/test_messages_proto2_proto.php index 5151492..b07331d 100644 --- a/generated/google/protobuf/test_messages_proto2_proto.php +++ b/generated/google/protobuf/test_messages_proto2_proto.php @@ -322,7 +322,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->a = $d->readVarint32Signed(); break; case 2: - if ($this->corecursive == null) $this->corecursive = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + if ($this->corecursive is null) { + $this->corecursive = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + } $this->corecursive->MergeFrom($d->readDecoder()); break; default: @@ -360,8 +362,10 @@ public function MergeJsonFrom(mixed $m): void { $this->a = \Protobuf\Internal\JsonDecoder::readInt32Signed($v); break; case 'corecursive': - if ($v === null) break; - if ($this->corecursive == null) $this->corecursive = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + if ($v is null) break; + if ($this->corecursive is null) { + $this->corecursive = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + } $this->corecursive->MergeJsonFrom($v); break; default: @@ -376,7 +380,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->a = $o->a; $tmp = $o->corecursive; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\TestAllTypesProto2(); $nv->CopyFrom($tmp); $this->corecursive = $nv; @@ -1756,7 +1760,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -1794,8 +1800,10 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + } $this->value->MergeJsonFrom($v); break; default: @@ -1810,7 +1818,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); $nv->CopyFrom($tmp); $this->value = $nv; @@ -1855,7 +1863,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -1893,8 +1903,10 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->value->MergeJsonFrom($v); break; default: @@ -1909,7 +1921,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\ForeignMessageProto2(); $nv->CopyFrom($tmp); $this->value = $nv; @@ -2839,11 +2851,15 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->optional_bytes = $d->readString(); break; case 18: - if ($this->optional_nested_message == null) $this->optional_nested_message = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + if ($this->optional_nested_message is null) { + $this->optional_nested_message = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + } $this->optional_nested_message->MergeFrom($d->readDecoder()); break; case 19: - if ($this->optional_foreign_message == null) $this->optional_foreign_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($this->optional_foreign_message is null) { + $this->optional_foreign_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->optional_foreign_message->MergeFrom($d->readDecoder()); break; case 21: @@ -2859,7 +2875,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->optional_cord = $d->readString(); break; case 27: - if ($this->recursive_message == null) $this->recursive_message = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + if ($this->recursive_message is null) { + $this->recursive_message = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + } $this->recursive_message->MergeFrom($d->readDecoder()); break; case 31: @@ -3443,7 +3461,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->oneof_field = new TestAllTypesProto2_oneof_field_oneof_enum(\protobuf_test_messages\proto2\TestAllTypesProto2_NestedEnum::FromInt($d->readVarint())); break; case 201: - if ($this->data == null) $this->data = new \protobuf_test_messages\proto2\TestAllTypesProto2_Data(); + if ($this->data is null) { + $this->data = new \protobuf_test_messages\proto2\TestAllTypesProto2_Data(); + } $this->data->MergeFrom($d->readDecoder()); break; case 241: @@ -4360,13 +4380,17 @@ public function MergeJsonFrom(mixed $m): void { $this->optional_bytes = \Protobuf\Internal\JsonDecoder::readBytes($v); break; case 'optional_nested_message': case 'optionalNestedMessage': - if ($v === null) break; - if ($this->optional_nested_message == null) $this->optional_nested_message = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + if ($v is null) break; + if ($this->optional_nested_message is null) { + $this->optional_nested_message = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); + } $this->optional_nested_message->MergeJsonFrom($v); break; case 'optional_foreign_message': case 'optionalForeignMessage': - if ($v === null) break; - if ($this->optional_foreign_message == null) $this->optional_foreign_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($v is null) break; + if ($this->optional_foreign_message is null) { + $this->optional_foreign_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->optional_foreign_message->MergeJsonFrom($v); break; case 'optional_nested_enum': case 'optionalNestedEnum': @@ -4382,8 +4406,10 @@ public function MergeJsonFrom(mixed $m): void { $this->optional_cord = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'recursive_message': case 'recursiveMessage': - if ($v === null) break; - if ($this->recursive_message == null) $this->recursive_message = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + if ($v is null) break; + if ($this->recursive_message is null) { + $this->recursive_message = new \protobuf_test_messages\proto2\TestAllTypesProto2(); + } $this->recursive_message->MergeJsonFrom($v); break; case 'repeated_int32': case 'repeatedInt32': @@ -4802,8 +4828,10 @@ public function MergeJsonFrom(mixed $m): void { $this->oneof_field = new TestAllTypesProto2_oneof_field_oneof_enum(\protobuf_test_messages\proto2\TestAllTypesProto2_NestedEnum::FromMixed($v)); break; case 'data': - if ($v === null) break; - if ($this->data == null) $this->data = new \protobuf_test_messages\proto2\TestAllTypesProto2_Data(); + if ($v is null) break; + if ($this->data is null) { + $this->data = new \protobuf_test_messages\proto2\TestAllTypesProto2_Data(); + } $this->data->MergeJsonFrom($v); break; case 'default_int32': case 'defaultInt32': @@ -4931,13 +4959,13 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->optional_string = $o->optional_string; $this->optional_bytes = $o->optional_bytes; $tmp = $o->optional_nested_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\TestAllTypesProto2_NestedMessage(); $nv->CopyFrom($tmp); $this->optional_nested_message = $nv; } $tmp = $o->optional_foreign_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\ForeignMessageProto2(); $nv->CopyFrom($tmp); $this->optional_foreign_message = $nv; @@ -4947,7 +4975,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->optional_string_piece = $o->optional_string_piece; $this->optional_cord = $o->optional_cord; $tmp = $o->recursive_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\TestAllTypesProto2(); $nv->CopyFrom($tmp); $this->recursive_message = $nv; @@ -5037,7 +5065,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->unpacked_bool = $o->unpacked_bool; $this->unpacked_nested_enum = $o->unpacked_nested_enum; $tmp = $o->data; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\TestAllTypesProto2_Data(); $nv->CopyFrom($tmp); $this->data = $nv; @@ -5279,11 +5307,15 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->optional_string = $d->readString(); break; case 1003: - if ($this->nested_message == null) $this->nested_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($this->nested_message is null) { + $this->nested_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->nested_message->MergeFrom($d->readDecoder()); break; case 1004: - if ($this->optionalgroup == null) $this->optionalgroup = new \protobuf_test_messages\proto2\UnknownToTestAllTypes_OptionalGroup(); + if ($this->optionalgroup is null) { + $this->optionalgroup = new \protobuf_test_messages\proto2\UnknownToTestAllTypes_OptionalGroup(); + } $this->optionalgroup->MergeFrom($d->readDecoder()); break; case 1006: @@ -5359,13 +5391,17 @@ public function MergeJsonFrom(mixed $m): void { $this->optional_string = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'nested_message': case 'nestedMessage': - if ($v === null) break; - if ($this->nested_message == null) $this->nested_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + if ($v is null) break; + if ($this->nested_message is null) { + $this->nested_message = new \protobuf_test_messages\proto2\ForeignMessageProto2(); + } $this->nested_message->MergeJsonFrom($v); break; case 'optionalgroup': - if ($v === null) break; - if ($this->optionalgroup == null) $this->optionalgroup = new \protobuf_test_messages\proto2\UnknownToTestAllTypes_OptionalGroup(); + if ($v is null) break; + if ($this->optionalgroup is null) { + $this->optionalgroup = new \protobuf_test_messages\proto2\UnknownToTestAllTypes_OptionalGroup(); + } $this->optionalgroup->MergeJsonFrom($v); break; case 'optional_bool': case 'optionalBool': @@ -5389,13 +5425,13 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->optional_int32 = $o->optional_int32; $this->optional_string = $o->optional_string; $tmp = $o->nested_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\ForeignMessageProto2(); $nv->CopyFrom($tmp); $this->nested_message = $nv; } $tmp = $o->optionalgroup; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto2\UnknownToTestAllTypes_OptionalGroup(); $nv->CopyFrom($tmp); $this->optionalgroup = $nv; diff --git a/generated/google/protobuf/test_messages_proto3_proto.php b/generated/google/protobuf/test_messages_proto3_proto.php index dee0de7..a77419b 100644 --- a/generated/google/protobuf/test_messages_proto3_proto.php +++ b/generated/google/protobuf/test_messages_proto3_proto.php @@ -381,7 +381,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->a = $d->readVarint32Signed(); break; case 2: - if ($this->corecursive == null) $this->corecursive = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + if ($this->corecursive is null) { + $this->corecursive = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + } $this->corecursive->MergeFrom($d->readDecoder()); break; default: @@ -419,8 +421,10 @@ public function MergeJsonFrom(mixed $m): void { $this->a = \Protobuf\Internal\JsonDecoder::readInt32Signed($v); break; case 'corecursive': - if ($v === null) break; - if ($this->corecursive == null) $this->corecursive = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + if ($v is null) break; + if ($this->corecursive is null) { + $this->corecursive = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + } $this->corecursive->MergeJsonFrom($v); break; default: @@ -435,7 +439,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->a = $o->a; $tmp = $o->corecursive; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\TestAllTypesProto3(); $nv->CopyFrom($tmp); $this->corecursive = $nv; @@ -1815,7 +1819,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -1853,8 +1859,10 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + } $this->value->MergeJsonFrom($v); break; default: @@ -1869,7 +1877,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); $nv->CopyFrom($tmp); $this->value = $nv; @@ -1914,7 +1922,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \protobuf_test_messages\proto3\ForeignMessage(); + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto3\ForeignMessage(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -1952,8 +1962,10 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \protobuf_test_messages\proto3\ForeignMessage(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \protobuf_test_messages\proto3\ForeignMessage(); + } $this->value->MergeJsonFrom($v); break; default: @@ -1968,7 +1980,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\ForeignMessage(); $nv->CopyFrom($tmp); $this->value = $nv; @@ -2653,11 +2665,15 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->optional_bytes = $d->readString(); break; case 18: - if ($this->optional_nested_message == null) $this->optional_nested_message = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + if ($this->optional_nested_message is null) { + $this->optional_nested_message = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + } $this->optional_nested_message->MergeFrom($d->readDecoder()); break; case 19: - if ($this->optional_foreign_message == null) $this->optional_foreign_message = new \protobuf_test_messages\proto3\ForeignMessage(); + if ($this->optional_foreign_message is null) { + $this->optional_foreign_message = new \protobuf_test_messages\proto3\ForeignMessage(); + } $this->optional_foreign_message->MergeFrom($d->readDecoder()); break; case 21: @@ -2676,7 +2692,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->optional_cord = $d->readString(); break; case 27: - if ($this->recursive_message == null) $this->recursive_message = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + if ($this->recursive_message is null) { + $this->recursive_message = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + } $this->recursive_message->MergeFrom($d->readDecoder()); break; case 31: @@ -3263,39 +3281,57 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->oneof_field = new TestAllTypesProto3_oneof_field_oneof_null_value(\google\protobuf\NullValue::FromInt($d->readVarint())); break; case 201: - if ($this->optional_bool_wrapper == null) $this->optional_bool_wrapper = new \google\protobuf\BoolValue(); + if ($this->optional_bool_wrapper is null) { + $this->optional_bool_wrapper = new \google\protobuf\BoolValue(); + } $this->optional_bool_wrapper->MergeFrom($d->readDecoder()); break; case 202: - if ($this->optional_int32_wrapper == null) $this->optional_int32_wrapper = new \google\protobuf\Int32Value(); + if ($this->optional_int32_wrapper is null) { + $this->optional_int32_wrapper = new \google\protobuf\Int32Value(); + } $this->optional_int32_wrapper->MergeFrom($d->readDecoder()); break; case 203: - if ($this->optional_int64_wrapper == null) $this->optional_int64_wrapper = new \google\protobuf\Int64Value(); + if ($this->optional_int64_wrapper is null) { + $this->optional_int64_wrapper = new \google\protobuf\Int64Value(); + } $this->optional_int64_wrapper->MergeFrom($d->readDecoder()); break; case 204: - if ($this->optional_uint32_wrapper == null) $this->optional_uint32_wrapper = new \google\protobuf\UInt32Value(); + if ($this->optional_uint32_wrapper is null) { + $this->optional_uint32_wrapper = new \google\protobuf\UInt32Value(); + } $this->optional_uint32_wrapper->MergeFrom($d->readDecoder()); break; case 205: - if ($this->optional_uint64_wrapper == null) $this->optional_uint64_wrapper = new \google\protobuf\UInt64Value(); + if ($this->optional_uint64_wrapper is null) { + $this->optional_uint64_wrapper = new \google\protobuf\UInt64Value(); + } $this->optional_uint64_wrapper->MergeFrom($d->readDecoder()); break; case 206: - if ($this->optional_float_wrapper == null) $this->optional_float_wrapper = new \google\protobuf\FloatValue(); + if ($this->optional_float_wrapper is null) { + $this->optional_float_wrapper = new \google\protobuf\FloatValue(); + } $this->optional_float_wrapper->MergeFrom($d->readDecoder()); break; case 207: - if ($this->optional_double_wrapper == null) $this->optional_double_wrapper = new \google\protobuf\DoubleValue(); + if ($this->optional_double_wrapper is null) { + $this->optional_double_wrapper = new \google\protobuf\DoubleValue(); + } $this->optional_double_wrapper->MergeFrom($d->readDecoder()); break; case 208: - if ($this->optional_string_wrapper == null) $this->optional_string_wrapper = new \google\protobuf\StringValue(); + if ($this->optional_string_wrapper is null) { + $this->optional_string_wrapper = new \google\protobuf\StringValue(); + } $this->optional_string_wrapper->MergeFrom($d->readDecoder()); break; case 209: - if ($this->optional_bytes_wrapper == null) $this->optional_bytes_wrapper = new \google\protobuf\BytesValue(); + if ($this->optional_bytes_wrapper is null) { + $this->optional_bytes_wrapper = new \google\protobuf\BytesValue(); + } $this->optional_bytes_wrapper->MergeFrom($d->readDecoder()); break; case 211: @@ -3344,27 +3380,39 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->repeated_bytes_wrapper []= $obj; break; case 301: - if ($this->optional_duration == null) $this->optional_duration = new \google\protobuf\Duration(); + if ($this->optional_duration is null) { + $this->optional_duration = new \google\protobuf\Duration(); + } $this->optional_duration->MergeFrom($d->readDecoder()); break; case 302: - if ($this->optional_timestamp == null) $this->optional_timestamp = new \google\protobuf\Timestamp(); + if ($this->optional_timestamp is null) { + $this->optional_timestamp = new \google\protobuf\Timestamp(); + } $this->optional_timestamp->MergeFrom($d->readDecoder()); break; case 303: - if ($this->optional_field_mask == null) $this->optional_field_mask = new \google\protobuf\FieldMask(); + if ($this->optional_field_mask is null) { + $this->optional_field_mask = new \google\protobuf\FieldMask(); + } $this->optional_field_mask->MergeFrom($d->readDecoder()); break; case 304: - if ($this->optional_struct == null) $this->optional_struct = new \google\protobuf\Struct(); + if ($this->optional_struct is null) { + $this->optional_struct = new \google\protobuf\Struct(); + } $this->optional_struct->MergeFrom($d->readDecoder()); break; case 305: - if ($this->optional_any == null) $this->optional_any = new \google\protobuf\Any(); + if ($this->optional_any is null) { + $this->optional_any = new \google\protobuf\Any(); + } $this->optional_any->MergeFrom($d->readDecoder()); break; case 306: - if ($this->optional_value == null) $this->optional_value = new \google\protobuf\Value(); + if ($this->optional_value is null) { + $this->optional_value = new \google\protobuf\Value(); + } $this->optional_value->MergeFrom($d->readDecoder()); break; case 307: @@ -4448,13 +4496,17 @@ public function MergeJsonFrom(mixed $m): void { $this->optional_bytes = \Protobuf\Internal\JsonDecoder::readBytes($v); break; case 'optional_nested_message': case 'optionalNestedMessage': - if ($v === null) break; - if ($this->optional_nested_message == null) $this->optional_nested_message = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + if ($v is null) break; + if ($this->optional_nested_message is null) { + $this->optional_nested_message = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); + } $this->optional_nested_message->MergeJsonFrom($v); break; case 'optional_foreign_message': case 'optionalForeignMessage': - if ($v === null) break; - if ($this->optional_foreign_message == null) $this->optional_foreign_message = new \protobuf_test_messages\proto3\ForeignMessage(); + if ($v is null) break; + if ($this->optional_foreign_message is null) { + $this->optional_foreign_message = new \protobuf_test_messages\proto3\ForeignMessage(); + } $this->optional_foreign_message->MergeJsonFrom($v); break; case 'optional_nested_enum': case 'optionalNestedEnum': @@ -4473,8 +4525,10 @@ public function MergeJsonFrom(mixed $m): void { $this->optional_cord = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'recursive_message': case 'recursiveMessage': - if ($v === null) break; - if ($this->recursive_message == null) $this->recursive_message = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + if ($v is null) break; + if ($this->recursive_message is null) { + $this->recursive_message = new \protobuf_test_messages\proto3\TestAllTypesProto3(); + } $this->recursive_message->MergeJsonFrom($v); break; case 'repeated_int32': case 'repeatedInt32': @@ -4896,48 +4950,66 @@ public function MergeJsonFrom(mixed $m): void { $this->oneof_field = new TestAllTypesProto3_oneof_field_oneof_null_value(\google\protobuf\NullValue::FromMixed($v)); break; case 'optional_bool_wrapper': case 'optionalBoolWrapper': - if ($v === null) break; - if ($this->optional_bool_wrapper == null) $this->optional_bool_wrapper = new \google\protobuf\BoolValue(); + if ($v is null) break; + if ($this->optional_bool_wrapper is null) { + $this->optional_bool_wrapper = new \google\protobuf\BoolValue(); + } $this->optional_bool_wrapper->MergeJsonFrom($v); break; case 'optional_int32_wrapper': case 'optionalInt32Wrapper': - if ($v === null) break; - if ($this->optional_int32_wrapper == null) $this->optional_int32_wrapper = new \google\protobuf\Int32Value(); + if ($v is null) break; + if ($this->optional_int32_wrapper is null) { + $this->optional_int32_wrapper = new \google\protobuf\Int32Value(); + } $this->optional_int32_wrapper->MergeJsonFrom($v); break; case 'optional_int64_wrapper': case 'optionalInt64Wrapper': - if ($v === null) break; - if ($this->optional_int64_wrapper == null) $this->optional_int64_wrapper = new \google\protobuf\Int64Value(); + if ($v is null) break; + if ($this->optional_int64_wrapper is null) { + $this->optional_int64_wrapper = new \google\protobuf\Int64Value(); + } $this->optional_int64_wrapper->MergeJsonFrom($v); break; case 'optional_uint32_wrapper': case 'optionalUint32Wrapper': - if ($v === null) break; - if ($this->optional_uint32_wrapper == null) $this->optional_uint32_wrapper = new \google\protobuf\UInt32Value(); + if ($v is null) break; + if ($this->optional_uint32_wrapper is null) { + $this->optional_uint32_wrapper = new \google\protobuf\UInt32Value(); + } $this->optional_uint32_wrapper->MergeJsonFrom($v); break; case 'optional_uint64_wrapper': case 'optionalUint64Wrapper': - if ($v === null) break; - if ($this->optional_uint64_wrapper == null) $this->optional_uint64_wrapper = new \google\protobuf\UInt64Value(); + if ($v is null) break; + if ($this->optional_uint64_wrapper is null) { + $this->optional_uint64_wrapper = new \google\protobuf\UInt64Value(); + } $this->optional_uint64_wrapper->MergeJsonFrom($v); break; case 'optional_float_wrapper': case 'optionalFloatWrapper': - if ($v === null) break; - if ($this->optional_float_wrapper == null) $this->optional_float_wrapper = new \google\protobuf\FloatValue(); + if ($v is null) break; + if ($this->optional_float_wrapper is null) { + $this->optional_float_wrapper = new \google\protobuf\FloatValue(); + } $this->optional_float_wrapper->MergeJsonFrom($v); break; case 'optional_double_wrapper': case 'optionalDoubleWrapper': - if ($v === null) break; - if ($this->optional_double_wrapper == null) $this->optional_double_wrapper = new \google\protobuf\DoubleValue(); + if ($v is null) break; + if ($this->optional_double_wrapper is null) { + $this->optional_double_wrapper = new \google\protobuf\DoubleValue(); + } $this->optional_double_wrapper->MergeJsonFrom($v); break; case 'optional_string_wrapper': case 'optionalStringWrapper': - if ($v === null) break; - if ($this->optional_string_wrapper == null) $this->optional_string_wrapper = new \google\protobuf\StringValue(); + if ($v is null) break; + if ($this->optional_string_wrapper is null) { + $this->optional_string_wrapper = new \google\protobuf\StringValue(); + } $this->optional_string_wrapper->MergeJsonFrom($v); break; case 'optional_bytes_wrapper': case 'optionalBytesWrapper': - if ($v === null) break; - if ($this->optional_bytes_wrapper == null) $this->optional_bytes_wrapper = new \google\protobuf\BytesValue(); + if ($v is null) break; + if ($this->optional_bytes_wrapper is null) { + $this->optional_bytes_wrapper = new \google\protobuf\BytesValue(); + } $this->optional_bytes_wrapper->MergeJsonFrom($v); break; case 'repeated_bool_wrapper': case 'repeatedBoolWrapper': @@ -5004,32 +5076,44 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'optional_duration': case 'optionalDuration': - if ($v === null) break; - if ($this->optional_duration == null) $this->optional_duration = new \google\protobuf\Duration(); + if ($v is null) break; + if ($this->optional_duration is null) { + $this->optional_duration = new \google\protobuf\Duration(); + } $this->optional_duration->MergeJsonFrom($v); break; case 'optional_timestamp': case 'optionalTimestamp': - if ($v === null) break; - if ($this->optional_timestamp == null) $this->optional_timestamp = new \google\protobuf\Timestamp(); + if ($v is null) break; + if ($this->optional_timestamp is null) { + $this->optional_timestamp = new \google\protobuf\Timestamp(); + } $this->optional_timestamp->MergeJsonFrom($v); break; case 'optional_field_mask': case 'optionalFieldMask': - if ($v === null) break; - if ($this->optional_field_mask == null) $this->optional_field_mask = new \google\protobuf\FieldMask(); + if ($v is null) break; + if ($this->optional_field_mask is null) { + $this->optional_field_mask = new \google\protobuf\FieldMask(); + } $this->optional_field_mask->MergeJsonFrom($v); break; case 'optional_struct': case 'optionalStruct': - if ($v === null) break; - if ($this->optional_struct == null) $this->optional_struct = new \google\protobuf\Struct(); + if ($v is null) break; + if ($this->optional_struct is null) { + $this->optional_struct = new \google\protobuf\Struct(); + } $this->optional_struct->MergeJsonFrom($v); break; case 'optional_any': case 'optionalAny': - if ($v === null) break; - if ($this->optional_any == null) $this->optional_any = new \google\protobuf\Any(); + if ($v is null) break; + if ($this->optional_any is null) { + $this->optional_any = new \google\protobuf\Any(); + } $this->optional_any->MergeJsonFrom($v); break; case 'optional_value': case 'optionalValue': - if ($this->optional_value == null) $this->optional_value = new \google\protobuf\Value(); + if ($this->optional_value is null) { + $this->optional_value = new \google\protobuf\Value(); + } $this->optional_value->MergeJsonFrom($v); break; case 'optional_null_value': case 'optionalNullValue': @@ -5164,13 +5248,13 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->optional_string = $o->optional_string; $this->optional_bytes = $o->optional_bytes; $tmp = $o->optional_nested_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\TestAllTypesProto3_NestedMessage(); $nv->CopyFrom($tmp); $this->optional_nested_message = $nv; } $tmp = $o->optional_foreign_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\ForeignMessage(); $nv->CopyFrom($tmp); $this->optional_foreign_message = $nv; @@ -5181,7 +5265,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->optional_string_piece = $o->optional_string_piece; $this->optional_cord = $o->optional_cord; $tmp = $o->recursive_message; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \protobuf_test_messages\proto3\TestAllTypesProto3(); $nv->CopyFrom($tmp); $this->recursive_message = $nv; @@ -5271,55 +5355,55 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->unpacked_bool = $o->unpacked_bool; $this->unpacked_nested_enum = $o->unpacked_nested_enum; $tmp = $o->optional_bool_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\BoolValue(); $nv->CopyFrom($tmp); $this->optional_bool_wrapper = $nv; } $tmp = $o->optional_int32_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Int32Value(); $nv->CopyFrom($tmp); $this->optional_int32_wrapper = $nv; } $tmp = $o->optional_int64_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Int64Value(); $nv->CopyFrom($tmp); $this->optional_int64_wrapper = $nv; } $tmp = $o->optional_uint32_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\UInt32Value(); $nv->CopyFrom($tmp); $this->optional_uint32_wrapper = $nv; } $tmp = $o->optional_uint64_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\UInt64Value(); $nv->CopyFrom($tmp); $this->optional_uint64_wrapper = $nv; } $tmp = $o->optional_float_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\FloatValue(); $nv->CopyFrom($tmp); $this->optional_float_wrapper = $nv; } $tmp = $o->optional_double_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\DoubleValue(); $nv->CopyFrom($tmp); $this->optional_double_wrapper = $nv; } $tmp = $o->optional_string_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\StringValue(); $nv->CopyFrom($tmp); $this->optional_string_wrapper = $nv; } $tmp = $o->optional_bytes_wrapper; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\BytesValue(); $nv->CopyFrom($tmp); $this->optional_bytes_wrapper = $nv; @@ -5370,37 +5454,37 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->repeated_bytes_wrapper []= $nv; } $tmp = $o->optional_duration; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Duration(); $nv->CopyFrom($tmp); $this->optional_duration = $nv; } $tmp = $o->optional_timestamp; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Timestamp(); $nv->CopyFrom($tmp); $this->optional_timestamp = $nv; } $tmp = $o->optional_field_mask; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\FieldMask(); $nv->CopyFrom($tmp); $this->optional_field_mask = $nv; } $tmp = $o->optional_struct; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Struct(); $nv->CopyFrom($tmp); $this->optional_struct = $nv; } $tmp = $o->optional_any; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Any(); $nv->CopyFrom($tmp); $this->optional_any = $nv; } $tmp = $o->optional_value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Value(); $nv->CopyFrom($tmp); $this->optional_value = $nv; diff --git a/generated/google/protobuf/type_proto.php b/generated/google/protobuf/type_proto.php index 788b6fb..a77123c 100644 --- a/generated/google/protobuf/type_proto.php +++ b/generated/google/protobuf/type_proto.php @@ -89,7 +89,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->options []= $obj; break; case 5: - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeFrom($d->readDecoder()); break; case 6: @@ -171,8 +173,10 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'source_context': case 'sourceContext': - if ($v === null) break; - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($v is null) break; + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeJsonFrom($v); break; case 'syntax': @@ -201,7 +205,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->options []= $nv; } $tmp = $o->source_context; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\SourceContext(); $nv->CopyFrom($tmp); $this->source_context = $nv; @@ -593,7 +597,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->options []= $obj; break; case 4: - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeFrom($d->readDecoder()); break; case 5: @@ -665,8 +671,10 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'source_context': case 'sourceContext': - if ($v === null) break; - if ($this->source_context == null) $this->source_context = new \google\protobuf\SourceContext(); + if ($v is null) break; + if ($this->source_context is null) { + $this->source_context = new \google\protobuf\SourceContext(); + } $this->source_context->MergeJsonFrom($v); break; case 'syntax': @@ -694,7 +702,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->options []= $nv; } $tmp = $o->source_context; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\SourceContext(); $nv->CopyFrom($tmp); $this->source_context = $nv; @@ -855,7 +863,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->name = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \google\protobuf\Any(); + if ($this->value is null) { + $this->value = new \google\protobuf\Any(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -893,8 +903,10 @@ public function MergeJsonFrom(mixed $m): void { $this->name = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \google\protobuf\Any(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \google\protobuf\Any(); + } $this->value->MergeJsonFrom($v); break; default: @@ -909,7 +921,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->name = $o->name; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Any(); $nv->CopyFrom($tmp); $this->value = $nv; diff --git a/generated/test/custom_optional_proto3.pb.bin b/generated/test/custom_optional_proto3.pb.bin new file mode 100644 index 0000000..484399c --- /dev/null +++ b/generated/test/custom_optional_proto3.pb.bin @@ -0,0 +1,3 @@ + …ëQ¸ @Ò "string*bytes0 +: + inner_stringB  any_bytes \ No newline at end of file diff --git a/generated/test/default_optional_proto3.pb.bin b/generated/test/default_optional_proto3.pb.bin new file mode 100644 index 0000000000000000000000000000000000000000..5207c4b759ef592e001e326df2e3542ad4635a2d GIT binary patch literal 23 Ycmd;NfC2#q2?iwwEd~PyD+VV900key = $d->readString(); break; case 2: - if ($this->value == null) $this->value = new \fiz\baz\example2(); + if ($this->value is null) { + $this->value = new \fiz\baz\example2(); + } $this->value->MergeFrom($d->readDecoder()); break; default: @@ -431,8 +433,10 @@ public function MergeJsonFrom(mixed $m): void { $this->key = \Protobuf\Internal\JsonDecoder::readString($v); break; case 'value': - if ($v === null) break; - if ($this->value == null) $this->value = new \fiz\baz\example2(); + if ($v is null) break; + if ($this->value is null) { + $this->value = new \fiz\baz\example2(); + } $this->value->MergeJsonFrom($v); break; default: @@ -447,7 +451,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { } $this->key = $o->key; $tmp = $o->value; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \fiz\baz\example2(); $nv->CopyFrom($tmp); $this->value = $nv; @@ -634,15 +638,21 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { } break; case 40: - if ($this->aexample2 == null) $this->aexample2 = new \foo\bar\example1_example2(); + if ($this->aexample2 is null) { + $this->aexample2 = new \foo\bar\example1_example2(); + } $this->aexample2->MergeFrom($d->readDecoder()); break; case 41: - if ($this->aexample22 == null) $this->aexample22 = new \foo\bar\example2(); + if ($this->aexample22 is null) { + $this->aexample22 = new \foo\bar\example2(); + } $this->aexample22->MergeFrom($d->readDecoder()); break; case 42: - if ($this->aexample23 == null) $this->aexample23 = new \fiz\baz\example2(); + if ($this->aexample23 is null) { + $this->aexample23 = new \fiz\baz\example2(); + } $this->aexample23->MergeFrom($d->readDecoder()); break; case 49: @@ -665,7 +675,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { $this->aoneof = new example1_aoneof_ooint($d->readVarint32Signed()); break; case 80: - if ($this->anany == null) $this->anany = new \google\protobuf\Any(); + if ($this->anany is null) { + $this->anany = new \google\protobuf\Any(); + } $this->anany->MergeFrom($d->readDecoder()); break; default: @@ -908,18 +920,24 @@ public function MergeJsonFrom(mixed $m): void { } break; case 'aexample2': - if ($v === null) break; - if ($this->aexample2 == null) $this->aexample2 = new \foo\bar\example1_example2(); + if ($v is null) break; + if ($this->aexample2 is null) { + $this->aexample2 = new \foo\bar\example1_example2(); + } $this->aexample2->MergeJsonFrom($v); break; case 'aexample22': - if ($v === null) break; - if ($this->aexample22 == null) $this->aexample22 = new \foo\bar\example2(); + if ($v is null) break; + if ($this->aexample22 is null) { + $this->aexample22 = new \foo\bar\example2(); + } $this->aexample22->MergeJsonFrom($v); break; case 'aexample23': - if ($v === null) break; - if ($this->aexample23 == null) $this->aexample23 = new \fiz\baz\example2(); + if ($v is null) break; + if ($this->aexample23 is null) { + $this->aexample23 = new \fiz\baz\example2(); + } $this->aexample23->MergeJsonFrom($v); break; case 'outoforder': @@ -948,8 +966,10 @@ public function MergeJsonFrom(mixed $m): void { $this->aoneof = new example1_aoneof_ooint(\Protobuf\Internal\JsonDecoder::readInt32Signed($v)); break; case 'anany': - if ($v === null) break; - if ($this->anany == null) $this->anany = new \google\protobuf\Any(); + if ($v is null) break; + if ($this->anany is null) { + $this->anany = new \google\protobuf\Any(); + } $this->anany->MergeJsonFrom($v); break; default: @@ -983,19 +1003,19 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->manystring = $o->manystring; $this->manyint64 = $o->manyint64; $tmp = $o->aexample2; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \foo\bar\example1_example2(); $nv->CopyFrom($tmp); $this->aexample2 = $nv; } $tmp = $o->aexample22; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \foo\bar\example2(); $nv->CopyFrom($tmp); $this->aexample22 = $nv; } $tmp = $o->aexample23; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \fiz\baz\example2(); $nv->CopyFrom($tmp); $this->aexample23 = $nv; @@ -1008,7 +1028,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { $this->amap2[$k] = $nv; } $tmp = $o->anany; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Any(); $nv->CopyFrom($tmp); $this->anany = $nv; diff --git a/generated/test/example2_proto.php b/generated/test/example2_proto.php index 76fbb9a..4c655a6 100644 --- a/generated/test/example2_proto.php +++ b/generated/test/example2_proto.php @@ -130,7 +130,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { list($fn, $wt) = $d->readTag(); switch ($fn) { case 1: - if ($this->funky == null) $this->funky = new \Funky(); + if ($this->funky is null) { + $this->funky = new \Funky(); + } $this->funky->MergeFrom($d->readDecoder()); break; default: @@ -160,8 +162,10 @@ public function MergeJsonFrom(mixed $m): void { foreach ($d as $k => $v) { switch ($k) { case 'funky': - if ($v === null) break; - if ($this->funky == null) $this->funky = new \Funky(); + if ($v is null) break; + if ($this->funky is null) { + $this->funky = new \Funky(); + } $this->funky->MergeJsonFrom($v); break; default: @@ -175,7 +179,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); } $tmp = $o->funky; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \Funky(); $nv->CopyFrom($tmp); $this->funky = $nv; diff --git a/generated/test/example3_proto.php b/generated/test/example3_proto.php index 56129ce..96e3f3a 100644 --- a/generated/test/example3_proto.php +++ b/generated/test/example3_proto.php @@ -183,11 +183,15 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { list($fn, $wt) = $d->readTag(); switch ($fn) { case 1: - if ($this->monkey == null) $this->monkey = new \Funky_Monkey(); + if ($this->monkey is null) { + $this->monkey = new \Funky_Monkey(); + } $this->monkey->MergeFrom($d->readDecoder()); break; case 2: - if ($this->dokey == null) $this->dokey = new \Donkey(); + if ($this->dokey is null) { + $this->dokey = new \Donkey(); + } $this->dokey->MergeFrom($d->readDecoder()); break; default: @@ -224,13 +228,17 @@ public function MergeJsonFrom(mixed $m): void { foreach ($d as $k => $v) { switch ($k) { case 'monkey': - if ($v === null) break; - if ($this->monkey == null) $this->monkey = new \Funky_Monkey(); + if ($v is null) break; + if ($this->monkey is null) { + $this->monkey = new \Funky_Monkey(); + } $this->monkey->MergeJsonFrom($v); break; case 'dokey': - if ($v === null) break; - if ($this->dokey == null) $this->dokey = new \Donkey(); + if ($v is null) break; + if ($this->dokey is null) { + $this->dokey = new \Donkey(); + } $this->dokey->MergeJsonFrom($v); break; default: @@ -244,13 +252,13 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); } $tmp = $o->monkey; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \Funky_Monkey(); $nv->CopyFrom($tmp); $this->monkey = $nv; } $tmp = $o->dokey; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \Donkey(); $nv->CopyFrom($tmp); $this->dokey = $nv; diff --git a/generated/test/example4_proto.php b/generated/test/example4_proto.php index 93cf98c..b066f01 100644 --- a/generated/test/example4_proto.php +++ b/generated/test/example4_proto.php @@ -106,7 +106,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { list($fn, $wt) = $d->readTag(); switch ($fn) { case 1: - if ($this->class == null) $this->class = new \pb_Class(); + if ($this->class is null) { + $this->class = new \pb_Class(); + } $this->class->MergeFrom($d->readDecoder()); break; default: @@ -136,8 +138,10 @@ public function MergeJsonFrom(mixed $m): void { foreach ($d as $k => $v) { switch ($k) { case 'class': - if ($v === null) break; - if ($this->class == null) $this->class = new \pb_Class(); + if ($v is null) break; + if ($this->class is null) { + $this->class = new \pb_Class(); + } $this->class->MergeJsonFrom($v); break; default: @@ -151,7 +155,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); } $tmp = $o->class; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \pb_Class(); $nv->CopyFrom($tmp); $this->class = $nv; diff --git a/generated/test/exampleany_proto.php b/generated/test/exampleany_proto.php index d367640..8912ba8 100644 --- a/generated/test/exampleany_proto.php +++ b/generated/test/exampleany_proto.php @@ -32,7 +32,9 @@ public function MergeFrom(\Protobuf\Internal\Decoder $d): void { list($fn, $wt) = $d->readTag(); switch ($fn) { case 1: - if ($this->any == null) $this->any = new \google\protobuf\Any(); + if ($this->any is null) { + $this->any = new \google\protobuf\Any(); + } $this->any->MergeFrom($d->readDecoder()); break; default: @@ -62,8 +64,10 @@ public function MergeJsonFrom(mixed $m): void { foreach ($d as $k => $v) { switch ($k) { case 'any': - if ($v === null) break; - if ($this->any == null) $this->any = new \google\protobuf\Any(); + if ($v is null) break; + if ($this->any is null) { + $this->any = new \google\protobuf\Any(); + } $this->any->MergeJsonFrom($v); break; default: @@ -77,7 +81,7 @@ public function CopyFrom(\Protobuf\Message $o): \Errors\Error { return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); } $tmp = $o->any; - if ($tmp !== null) { + if ($tmp is nonnull) { $nv = new \google\protobuf\Any(); $nv->CopyFrom($tmp); $this->any = $nv; diff --git a/generated/test/optional_proto3_file_descriptor.pb.bin.gz b/generated/test/optional_proto3_file_descriptor.pb.bin.gz new file mode 100644 index 0000000000000000000000000000000000000000..a6dce9e9dac1d92ac4c3c074c6a35f50f9e38277 GIT binary patch literal 333 zcmV-T0kZyh+H_FOYU3~v&cyNG?6Moo9+WI8CiLKw4Qa`xr@AeuhhFpoMy9R_I8un^ zgYyJ=&Av&IWTz15Nt*e7nD4`-s#=xFgW5^Ko8oYkO5UaBiJX$3mWx`-x~Vd=D!Y%2 zi{9evPY3^ADWeto{9SfsQxS+E0Xkvh;tUY|N00A>+TN3C42eU54YLLp=<-s^hBz@K z0i7~CYDn9*>bMg%nZ=NV)M4Xdv@Ls8wZx4f`AuhRm^Ju-9v7A9_QZ=J`Lnr6OMXhP zBfkn!9bZJZr!E`#TD-*>-?ugKV@Q5&RzFMM+M0UIkhLyDmkTa>5*XpX)Yh1eHKvcE zr#`c!Gr;l|gV84<-)VJ;;U(*Of#K!Q$VGUXPxSLV#~d*zhNkln{lfN|2j~^1MoX|h fmS7sPUz0cY(JgcUE7F&hp3V3b00960JXf2z00^vx literal 0 HcmV?d00001 diff --git a/generated/test/optional_proto3_proto.php b/generated/test/optional_proto3_proto.php new file mode 100644 index 0000000..22a9b99 --- /dev/null +++ b/generated/test/optional_proto3_proto.php @@ -0,0 +1,535 @@ + $itos = dict[ + 0 => 'C', + 10 => 'D', + ]; + public static function ToStringDict(): dict { + return self::$itos; + } + private static dict $stoi = dict[ + 'C' => 0, + 'D' => 10, + ]; + public static function FromMixed(mixed $m): optional_proto3_InnerEnum_enum_t { + if ($m is string) return idx(self::$stoi, $m, \is_numeric($m) ? ((int) $m) : 0); + if ($m is int) return $m; + return 0; + } + public static function FromInt(int $i): optional_proto3_InnerEnum_enum_t { + return $i; + } +} + +class optional_proto3_InnerMsg implements \Protobuf\Message { + public string $astring; + private string $XXX_unrecognized; + + public function __construct(shape( + ?'astring' => string, + ) $s = shape()) { + $this->astring = $s['astring'] ?? ''; + $this->XXX_unrecognized = ''; + } + + public function MessageName(): string { + return "baz.optional_proto3.InnerMsg"; + } + + public static function ParseFrom(string $input): ?optional_proto3_InnerMsg { + $msg = new optional_proto3_InnerMsg(); + $e = \Protobuf\Unmarshal($input, $msg); + if (!$e->Ok()) { + return null; + } + return $msg; + } + + public function MergeFrom(\Protobuf\Internal\Decoder $d): void { + while (!$d->isEOF()){ + list($fn, $wt) = $d->readTag(); + switch ($fn) { + case 1: + $this->astring = $d->readString(); + break; + default: + $d->skip($fn, $wt); + } + } + $this->XXX_unrecognized = $d->skippedRaw(); + } + + public function WriteTo(\Protobuf\Internal\Encoder $e): void { + if ($this->astring !== '') { + $e->writeTag(1, 2); + $e->writeString($this->astring); + } + $e->writeRaw($this->XXX_unrecognized); + } + + public function WriteJsonTo(\Protobuf\Internal\JsonEncoder $e): void { + $e->writeString('astring', 'astring', $this->astring, false); + } + + public function MergeJsonFrom(mixed $m): void { + if ($m === null) return; + $d = \Protobuf\Internal\JsonDecoder::readObject($m); + foreach ($d as $k => $v) { + switch ($k) { + case 'astring': + $this->astring = \Protobuf\Internal\JsonDecoder::readString($v); + break; + default: + break; + } + } + } + + public function CopyFrom(\Protobuf\Message $o): \Errors\Error { + if (!($o is optional_proto3_InnerMsg)) { + return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); + } + $this->astring = $o->astring; + $this->XXX_unrecognized = $o->XXX_unrecognized; + return \Errors\Ok(); + } +} + +class optional_proto3 implements \Protobuf\Message { + private float $adouble; + private bool $was_adouble_set; + private int $aint64; + private bool $was_aint64_set; + private bool $abool; + private bool $was_abool_set; + private string $astring; + private bool $was_astring_set; + private string $abytes; + private bool $was_abytes_set; + private \baz\optional_proto3_InnerEnum_enum_t $anenum; + private bool $was_anenum_set; + private ?\baz\optional_proto3_InnerMsg $amsg; + private bool $was_amsg_set; + private ?\google\protobuf\Any $anany; + private bool $was_anany_set; + private string $XXX_unrecognized; + + public function __construct(shape( + ?'adouble' => float, + ?'aint64' => int, + ?'abool' => bool, + ?'astring' => string, + ?'abytes' => string, + ?'anenum' => \baz\optional_proto3_InnerEnum_enum_t, + ?'amsg' => ?\baz\optional_proto3_InnerMsg, + ?'anany' => ?\google\protobuf\Any, + ) $s = shape()) { + if (Shapes::keyExists($s, 'adouble')) { + $this->adouble = $s['adouble']; + $this->was_adouble_set = true; + } else { + $this->adouble = 0.0; + $this->was_adouble_set = false; + } + if (Shapes::keyExists($s, 'aint64')) { + $this->aint64 = $s['aint64']; + $this->was_aint64_set = true; + } else { + $this->aint64 = 0; + $this->was_aint64_set = false; + } + if (Shapes::keyExists($s, 'abool')) { + $this->abool = $s['abool']; + $this->was_abool_set = true; + } else { + $this->abool = false; + $this->was_abool_set = false; + } + if (Shapes::keyExists($s, 'astring')) { + $this->astring = $s['astring']; + $this->was_astring_set = true; + } else { + $this->astring = ''; + $this->was_astring_set = false; + } + if (Shapes::keyExists($s, 'abytes')) { + $this->abytes = $s['abytes']; + $this->was_abytes_set = true; + } else { + $this->abytes = ''; + $this->was_abytes_set = false; + } + if (Shapes::keyExists($s, 'anenum')) { + $this->anenum = $s['anenum']; + $this->was_anenum_set = true; + } else { + $this->anenum = \baz\optional_proto3_InnerEnum::FromInt(0); + $this->was_anenum_set = false; + } + if (Shapes::keyExists($s, 'amsg')) { + $this->amsg = $s['amsg']; + $this->was_amsg_set = true; + } else { + $this->amsg = null; + $this->was_amsg_set = false; + } + if (Shapes::keyExists($s, 'anany')) { + $this->anany = $s['anany']; + $this->was_anany_set = true; + } else { + $this->anany = null; + $this->was_anany_set = false; + } + $this->XXX_unrecognized = ''; + } + + public function getAdouble(): float { + return $this->adouble; + } + + public function setAdouble(float $v): void { + $this->adouble = $v; + $this->was_adouble_set = true; + } + + public function hasAdouble(): bool { + return $this->was_adouble_set; + } + + public function getAint64(): int { + return $this->aint64; + } + + public function setAint64(int $v): void { + $this->aint64 = $v; + $this->was_aint64_set = true; + } + + public function hasAint64(): bool { + return $this->was_aint64_set; + } + + public function getAbool(): bool { + return $this->abool; + } + + public function setAbool(bool $v): void { + $this->abool = $v; + $this->was_abool_set = true; + } + + public function hasAbool(): bool { + return $this->was_abool_set; + } + + public function getAstring(): string { + return $this->astring; + } + + public function setAstring(string $v): void { + $this->astring = $v; + $this->was_astring_set = true; + } + + public function hasAstring(): bool { + return $this->was_astring_set; + } + + public function getAbytes(): string { + return $this->abytes; + } + + public function setAbytes(string $v): void { + $this->abytes = $v; + $this->was_abytes_set = true; + } + + public function hasAbytes(): bool { + return $this->was_abytes_set; + } + + public function getAnenum(): \baz\optional_proto3_InnerEnum_enum_t { + return $this->anenum; + } + + public function setAnenum(\baz\optional_proto3_InnerEnum_enum_t $v): void { + $this->anenum = $v; + $this->was_anenum_set = true; + } + + public function hasAnenum(): bool { + return $this->was_anenum_set; + } + + public function getAmsg(): ?\baz\optional_proto3_InnerMsg { + return $this->amsg; + } + + public function setAmsg(?\baz\optional_proto3_InnerMsg $v): void { + $this->amsg = $v; + $this->was_amsg_set = true; + } + + public function hasAmsg(): bool { + return $this->was_amsg_set; + } + + public function getAnany(): ?\google\protobuf\Any { + return $this->anany; + } + + public function setAnany(?\google\protobuf\Any $v): void { + $this->anany = $v; + $this->was_anany_set = true; + } + + public function hasAnany(): bool { + return $this->was_anany_set; + } + + public function MessageName(): string { + return "baz.optional_proto3"; + } + + public static function ParseFrom(string $input): ?optional_proto3 { + $msg = new optional_proto3(); + $e = \Protobuf\Unmarshal($input, $msg); + if (!$e->Ok()) { + return null; + } + return $msg; + } + + public function MergeFrom(\Protobuf\Internal\Decoder $d): void { + while (!$d->isEOF()){ + list($fn, $wt) = $d->readTag(); + switch ($fn) { + case 1: + $this->adouble = $d->readDouble(); + $this->was_adouble_set = true; + break; + case 2: + $this->aint64 = $d->readVarint(); + $this->was_aint64_set = true; + break; + case 3: + $this->abool = $d->readBool(); + $this->was_abool_set = true; + break; + case 4: + $this->astring = $d->readString(); + $this->was_astring_set = true; + break; + case 5: + $this->abytes = $d->readString(); + $this->was_abytes_set = true; + break; + case 6: + $this->anenum = \baz\optional_proto3_InnerEnum::FromInt($d->readVarint()); + $this->was_anenum_set = true; + break; + case 7: + if ($this->amsg is null) { + $this->amsg = new \baz\optional_proto3_InnerMsg(); + $this->was_amsg_set = true; + } + $this->amsg->MergeFrom($d->readDecoder()); + break; + case 8: + if ($this->anany is null) { + $this->anany = new \google\protobuf\Any(); + $this->was_anany_set = true; + } + $this->anany->MergeFrom($d->readDecoder()); + break; + default: + $d->skip($fn, $wt); + } + } + $this->XXX_unrecognized = $d->skippedRaw(); + } + + public function WriteTo(\Protobuf\Internal\Encoder $e): void { + if ($this->was_adouble_set) { + $e->writeTag(1, 1); + $e->writeDouble($this->adouble); + } + if ($this->was_aint64_set) { + $e->writeTag(2, 0); + $e->writeVarint($this->aint64); + } + if ($this->was_abool_set) { + $e->writeTag(3, 0); + $e->writeBool($this->abool); + } + if ($this->was_astring_set) { + $e->writeTag(4, 2); + $e->writeString($this->astring); + } + if ($this->was_abytes_set) { + $e->writeTag(5, 2); + $e->writeString($this->abytes); + } + if ($this->was_anenum_set) { + $e->writeTag(6, 0); + $e->writeVarint($this->anenum); + } + $msg = $this->amsg; + if ($msg != null) { + if ($this->was_amsg_set) { + $nested = new \Protobuf\Internal\Encoder(); + $msg->WriteTo($nested); + $e->writeEncoder($nested, 7); + } + } + $msg = $this->anany; + if ($msg != null) { + if ($this->was_anany_set) { + $nested = new \Protobuf\Internal\Encoder(); + $msg->WriteTo($nested); + $e->writeEncoder($nested, 8); + } + } + $e->writeRaw($this->XXX_unrecognized); + } + + public function WriteJsonTo(\Protobuf\Internal\JsonEncoder $e): void { + if ($this->hasAdouble()) { + $e->writeFloat('adouble', 'adouble', $this->adouble, false); + } + if ($this->hasAint64()) { + $e->writeInt64Signed('aint64', 'aint64', $this->aint64, false); + } + if ($this->hasAbool()) { + $e->writeBool('abool', 'abool', $this->abool, false); + } + if ($this->hasAstring()) { + $e->writeString('astring', 'astring', $this->astring, false); + } + if ($this->hasAbytes()) { + $e->writeBytes('abytes', 'abytes', $this->abytes, false); + } + if ($this->hasAnenum()) { + $e->writeEnum('anenum', 'anenum', \baz\optional_proto3_InnerEnum::ToStringDict(), $this->anenum, false); + } + if ($this->hasAmsg()) { + $e->writeMessage('amsg', 'amsg', $this->amsg, false); + } + if ($this->hasAnany()) { + $e->writeMessage('anany', 'anany', $this->anany, false); + } + } + + public function MergeJsonFrom(mixed $m): void { + if ($m === null) return; + $d = \Protobuf\Internal\JsonDecoder::readObject($m); + foreach ($d as $k => $v) { + switch ($k) { + case 'adouble': + $this->adouble = \Protobuf\Internal\JsonDecoder::readFloat($v); + $this->was_adouble_set = true; + break; + case 'aint64': + $this->aint64 = \Protobuf\Internal\JsonDecoder::readInt64Signed($v); + $this->was_aint64_set = true; + break; + case 'abool': + $this->abool = \Protobuf\Internal\JsonDecoder::readBool($v); + $this->was_abool_set = true; + break; + case 'astring': + $this->astring = \Protobuf\Internal\JsonDecoder::readString($v); + $this->was_astring_set = true; + break; + case 'abytes': + $this->abytes = \Protobuf\Internal\JsonDecoder::readBytes($v); + $this->was_abytes_set = true; + break; + case 'anenum': + $this->anenum = \baz\optional_proto3_InnerEnum::FromMixed($v); + $this->was_anenum_set = true; + break; + case 'amsg': + if ($v is null) break; + if ($this->amsg is null) { + $this->amsg = new \baz\optional_proto3_InnerMsg(); + $this->was_amsg_set = true; + } + $this->amsg->MergeJsonFrom($v); + break; + case 'anany': + if ($v is null) break; + if ($this->anany is null) { + $this->anany = new \google\protobuf\Any(); + $this->was_anany_set = true; + } + $this->anany->MergeJsonFrom($v); + break; + default: + break; + } + } + } + + public function CopyFrom(\Protobuf\Message $o): \Errors\Error { + if (!($o is optional_proto3)) { + return \Errors\Errorf('CopyFrom failed: incorrect type received: %s', $o->MessageName()); + } + if ($o->hasAdouble()) { + $this->adouble = $o->adouble; + } + if ($o->hasAint64()) { + $this->aint64 = $o->aint64; + } + if ($o->hasAbool()) { + $this->abool = $o->abool; + } + if ($o->hasAstring()) { + $this->astring = $o->astring; + } + if ($o->hasAbytes()) { + $this->abytes = $o->abytes; + } + if ($o->hasAnenum()) { + $this->anenum = $o->anenum; + } + $tmp = $o->amsg; + if ($tmp is nonnull) { + $nv = new \baz\optional_proto3_InnerMsg(); + $nv->CopyFrom($tmp); + $this->setAmsg($nv); + } else if ($o->hasAmsg()) { + $this->setAmsg(null); + } + $tmp = $o->anany; + if ($tmp is nonnull) { + $nv = new \google\protobuf\Any(); + $nv->CopyFrom($tmp); + $this->setAnany($nv); + } else if ($o->hasAnany()) { + $this->setAnany(null); + } + $this->XXX_unrecognized = $o->XXX_unrecognized; + return \Errors\Ok(); + } +} + + +class XXX_FileDescriptor_test_optional_proto3__proto implements \Protobuf\Internal\FileDescriptor { + const string NAME = 'test/optional_proto3.proto'; + public function Name(): string { + return self::NAME; + } + + public function FileDescriptorProtoBytes(): string { + return (string)\gzuncompress(\file_get_contents(\realpath(\dirname(__FILE__)) . '/optional_proto3_file_descriptor.pb.bin.gz')); + } +} diff --git a/protoc-gen-hack/plugin.go b/protoc-gen-hack/plugin.go index ae0c13d..622295b 100644 --- a/protoc-gen-hack/plugin.go +++ b/protoc-gen-hack/plugin.go @@ -87,6 +87,8 @@ const ( func gen(req *ppb.CodeGeneratorRequest) *ppb.CodeGeneratorResponse { resp := &ppb.CodeGeneratorResponse{} + features := uint64(ppb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) + resp.SupportedFeatures = &features fileToGenerate := map[string]bool{} for _, f := range req.FileToGenerate { fileToGenerate[f] = true @@ -596,7 +598,12 @@ func (f *field) writeDecoder(w *writer, dec, wt string) { w.p("$this->%s = new %s($obj);", f.oneof.name, f.oneof.classNameForField(f)) w.p("}") } else { - w.p("if ($this->%s == null) $this->%s = new %s();", f.varName(), f.varName(), f.phpType()) + w.p("if ($this->%s is null) {", f.varName()) + w.p("$this->%s = new %s();", f.varName(), f.phpType()) + if f.isProto3Optional() { + w.p("$this->was_%s_set = true;", f.varName()) + } + w.p("}") w.p("$this->%s->MergeFrom(%s->readDecoder());", f.varName(), dec) } } @@ -644,6 +651,9 @@ func (f *field) writeDecoder(w *writer, dec, wt string) { } if !f.isRepeated() { w.p("$this->%s = %s;", f.varName(), reader) + if f.isProto3Optional() { + w.p("$this->was_%s_set = true;", f.varName()) + } return } // Repeated @@ -742,9 +752,15 @@ func (f field) writeEncoder(w *writer, enc string, alwaysEmitDefaultValue bool) w.p("$msg = $this->%s;", f.varName()) w.p("if ($msg != null) {") } + if f.isProto3Optional() { + w.p("if ($this->was_%s_set) {", f.varName()) + } w.p("$nested = new %s\\Encoder();", libNsInternal) w.p("$msg->WriteTo($nested);") w.p("%s->writeEncoder($nested, %d);", enc, f.fd.GetNumber()) + if f.isProto3Optional() { + w.p("}") + } w.p("}") return } @@ -752,12 +768,14 @@ func (f field) writeEncoder(w *writer, enc string, alwaysEmitDefaultValue bool) tagWriter, writer := f.primitiveWriters(enc) if !f.isRepeated() { - if !alwaysEmitDefaultValue { + if f.isProto3Optional() { + w.p("if ($this->was_%s_set) {", f.varName()) + } else if !alwaysEmitDefaultValue { w.p("if ($this->%s !== %s) {", f.varName(), f.defaultValue()) } w.p(tagWriter) w.p("%s;", writer) - if !alwaysEmitDefaultValue { + if f.isProto3Optional() || !alwaysEmitDefaultValue { w.p("}") } return @@ -810,13 +828,27 @@ func (f field) writeCopy(w *writer, c string) { if f.isMessageOrGroup() { w.p("$tmp = %s->%s;", c, f.varName()) - w.p("if ($tmp !== null) {") + w.p("if ($tmp is nonnull) {") w.p("$nv = new %s();", f.phpType()) w.p("$nv->CopyFrom($tmp);") - w.p("$this->%s = $nv;", f.varName()) + if f.isProto3Optional() { + camelCaseName := camelCase(f.varName()) + w.p("$this->set%s($nv);", camelCaseName) + w.p("} else if (%s->has%s()) {", c, camelCaseName) + w.p("$this->set%s(null);", camelCaseName) + } else { + w.p("$this->%s = $nv;", f.varName()) + } w.p("}") } else { + if f.isProto3Optional() { + camelCaseName := camelCase(f.varName()) + w.p("if (%s->has%s()) {", c, camelCaseName) + } w.p("$this->%s = %s->%s;", f.varName(), c, f.varName()) + if f.isProto3Optional() { + w.p("}") + } } } @@ -1008,6 +1040,9 @@ func (f *field) writeJsonDecoder(w *writer, v string) { w.p("$this->%s[%s] = $obj;", f.fd.GetName(), kjr) } else { w.p("$this->%s[%s] = %s;", f.fd.GetName(), kjr, vv.jsonReader("$v")) + if f.isProto3Optional() { + w.p("$this->was_%s_set = true;", f.fd.GetName()) + } } w.p("}") w.p("}") @@ -1029,9 +1064,14 @@ func (f *field) writeJsonDecoder(w *writer, v string) { w.p("$this->%s = new %s($obj);", f.oneof.name, f.oneof.classNameForField(f)) } else { if f.typeFqProtoName != ".google.protobuf.Value" { // A special little snow flake! - w.p("if ($v === null) break;") + w.p("if ($v is null) break;") + } + w.p("if ($this->%s is null) {", f.varName()) + w.p("$this->%s = new %s();", f.varName(), f.phpType()) + if f.isProto3Optional() { + w.p("$this->was_%s_set = true;", f.varName()) } - w.p("if ($this->%s == null) $this->%s = new %s();", f.varName(), f.varName(), f.phpType()) + w.p("}") w.p("$this->%s->MergeJsonFrom(%s);", f.varName(), v) } } @@ -1048,6 +1088,9 @@ func (f *field) writeJsonDecoder(w *writer, v string) { w.p("$this->%s = new %s(%s);", f.oneof.name, f.oneof.classNameForField(f), f.jsonReader(v)) } else { w.p("$this->%s = %s;", f.varName(), f.jsonReader(v)) + if f.isProto3Optional() { + w.p("$this->was_%s_set = true;", f.varName()) + } } } } @@ -1115,16 +1158,30 @@ func (f field) writeJsonEncoder(w *writer, enc string, forceEmitDefault bool) { emitDefault = "" } + if f.isProto3Optional() { + camelCaseName := camelCase(f.fd.GetName()) + w.p("if ($this->has%s()) {", camelCaseName) + } if writer == "Enum" { itos := f.typePhpNs + "\\" + f.typePhpName + "::ToStringDict()" w.p("%s->writeEnum%s('%s', '%s', %s, $this->%s%s);", enc, repeated, f.fd.GetName(), f.fd.GetJsonName(), itos, f.varName(), emitDefault) } else { w.p("%s->write%s%s('%s', '%s', $this->%s%s);", enc, writer, repeated, f.fd.GetName(), f.fd.GetJsonName(), f.varName(), emitDefault) } + if f.isProto3Optional() { + w.p("}") + } +} + +func (f *field) isOneofMember() bool { + // optional fields in proto3 are turned into a synthetic oneoff. + // https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md#updating-a-code-generator + // We should not process them as oneoff but as their underlying type. + return f.fd.OneofIndex != nil && !f.isProto3Optional() } -func (f field) isOneofMember() bool { - return f.fd.OneofIndex != nil +func (f *field) isProto3Optional() bool { + return f.fd.Proto3Optional != nil && *f.fd.Proto3Optional } // writeEnum writes an enumeration type and constants definitions. @@ -1301,6 +1358,16 @@ func isWrapperType(fqn string) bool { return false } +func camelCase(in string) string { + words := strings.Split(in, "_") + camelCaseName := "" + for _, word := range words { + camelCaseName += strings.ToUpper(word[:1]) + camelCaseName += word[1:] + } + return camelCaseName +} + // https://github.com/golang/protobuf/blob/master/protoc-gen-go/descriptor/descriptor.pb.go func writeDescriptor(w *writer, dp *desc.DescriptorProto, ns *Namespace, prefixNames []string, syn syntax) { nextNames := append(prefixNames, dp.GetName()) @@ -1332,6 +1399,12 @@ func writeDescriptor(w *writer, dp *desc.DescriptorProto, ns *Namespace, prefixN // Write oneof types. oneofs := []*oneof{} for i, od := range dp.OneofDecl { + // Synthetic one-off for optional in proto3 starts with an underscore. + // TODO: This may clash with legitimate names starting with an underscore. + // But this seems like a theoretical issue right now. + if od.GetName()[0] == '_' { + continue + } oneofName := strings.Join(append(nextNames, od.GetName()), "_") oo := &oneof{ descriptor: od, @@ -1367,7 +1440,15 @@ func writeDescriptor(w *writer, dp *desc.DescriptorProto, ns *Namespace, prefixN continue } // w.p("// field %s = %d", f.fd.GetName(), f.fd.GetNumber()) - w.p("public %s $%s;", f.labeledType(), f.varName()) + if f.isProto3Optional() { + // To keep the presence bit in sync, we must switch to + // an explicit setter and make those fields private. + // TODO: We should make all usage go through getters/setters. + w.p("private %s $%s;", f.labeledType(), f.varName()) + w.p("private bool $was_%s_set;", f.varName()) + } else { + w.p("public %s $%s;", f.labeledType(), f.varName()) + } } for _, oo := range oneofs { w.p("public %s $%s;", oo.interfaceName, oo.name) @@ -1393,7 +1474,18 @@ func writeDescriptor(w *writer, dp *desc.DescriptorProto, ns *Namespace, prefixN if f.isOneofMember() { continue } - w.p("$this->%s = $s['%s'] ?? %s;", f.varName(), f.varName(), f.defaultValue()) + if f.isProto3Optional() { + varName := f.varName() + w.p("if (Shapes::keyExists($s, '%s')) {", varName) + w.p("$this->%s = $s['%s'];", varName, varName) + w.p("$this->was_%s_set = true;", varName) + w.p("} else {") + w.p("$this->%s = %s;", varName, f.defaultValue()) + w.p("$this->was_%s_set = false;", varName) + w.p("}") + } else { + w.p("$this->%s = $s['%s'] ?? %s;", f.varName(), f.varName(), f.defaultValue()) + } } for _, oo := range oneofs { w.p("$this->%s = $s['%s'] ?? new %s();", oo.name, oo.name, oo.notsetClass) @@ -1402,6 +1494,29 @@ func writeDescriptor(w *writer, dp *desc.DescriptorProto, ns *Namespace, prefixN w.p("}") w.ln() + // Getters, setters & presence checks. + for _, f := range fields { + if !f.isProto3Optional() { + continue + } + camelCaseName := camelCase(f.varName()) + w.p("public function get%s(): %s {", camelCaseName, f.labeledType()) + w.p("return $this->%s;", f.varName()) + w.p("}") + w.ln() + + w.p("public function set%s(%s $v): void {", camelCaseName, f.labeledType()) + w.p("$this->%s = $v;", f.varName()) + w.p("$this->was_%s_set = true;", f.varName()) + w.p("}") + w.ln() + + w.p("public function has%s(): bool {", camelCaseName) + w.p("return $this->was_%s_set;", f.varName()) + w.p("}") + w.ln() + } + fqProtoType := ns.Fqn fqProtoType += strings.Join(append(prefixNames, dp.GetName()), ".") diff --git a/test/custom_optional_proto3.pb.txt b/test/custom_optional_proto3.pb.txt new file mode 100644 index 0000000..f4cfac9 --- /dev/null +++ b/test/custom_optional_proto3.pb.txt @@ -0,0 +1,15 @@ +adouble: 3.14 +aint64: 1234 +abool: true +astring: "string" +abytes: "bytes" + +anenum: D + +amsg { + astring: "inner_string" +} + +anany { + value: "any_bytes" +} diff --git a/test/default_optional_proto3.pb.txt b/test/default_optional_proto3.pb.txt new file mode 100644 index 0000000..3675b94 --- /dev/null +++ b/test/default_optional_proto3.pb.txt @@ -0,0 +1,13 @@ +adouble: 0.0 +aint64: 0 +abool: false +astring: "" +abytes: "" + +anenum: C + +amsg { +} + +anany { +} diff --git a/test/empty_optional_proto3.pb.txt b/test/empty_optional_proto3.pb.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/mixed_optional_proto3.pb.json b/test/mixed_optional_proto3.pb.json new file mode 100644 index 0000000..256aedb --- /dev/null +++ b/test/mixed_optional_proto3.pb.json @@ -0,0 +1,13 @@ +{ + "adouble": 3.14, + "aint64": 1234, + "abool": false, + "abytes": "bytes", + "anenum": 10, + "amsg": { + "astring": "inner_string" + }, + "anany": { + "value": "any_bytes" + } +} diff --git a/test/optional_proto3.proto b/test/optional_proto3.proto new file mode 100644 index 0000000..5fb6193 --- /dev/null +++ b/test/optional_proto3.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package baz; + +import "google/protobuf/any.proto"; + +message optional_proto3 { + // Scalars. + optional double adouble = 1; + optional int64 aint64 = 2; + optional bool abool = 3; + optional string astring = 4; + optional bytes abytes = 5; + + // Enums + enum InnerEnum { + C = 0; + D = 10; + } + optional InnerEnum anenum = 6; + + // Nested Message. + message InnerMsg { + string astring = 1; + } + optional InnerMsg amsg = 7; + + optional google.protobuf.Any anany = 8; +} diff --git a/test/test.php b/test/test.php index 478b21e..391a65d 100644 --- a/test/test.php +++ b/test/test.php @@ -13,6 +13,7 @@ function main(): void { require "generated/test/example2_proto.php"; require "generated/test/example4_proto.php"; require "generated/test/exampleany_proto.php"; + require "generated/test/optional_proto3_proto.php"; require "generated/google/protobuf/descriptor_proto.php"; require "test/test_suite.php"; @@ -70,6 +71,9 @@ function main(): void { // Any testAny(); + // Optional in proto3 + testOptionalProto3(); + // Service testLoopbackService(); } diff --git a/test/test_suite.php b/test/test_suite.php index c3479ba..f55f286 100644 --- a/test/test_suite.php +++ b/test/test_suite.php @@ -166,6 +166,10 @@ function testDescriptorReflection(): void { $dp->package, ); } + + + // TODO: We need to check reflection on optional proto3. + // https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md#implementation-changes } function testReservedClassNames(): void { @@ -237,6 +241,102 @@ public function WithOutgoingMetadata(\Grpc\Metadata $m): \Grpc\Context { } } +function testOptionalProto3(): void { + echo "Testing empty optional proto3 proto: "; + $msg = new \baz\optional_proto3(); + Protobuf\Unmarshal(file_get_contents('generated/test/empty_optional_proto3.pb.bin'), $msg); + a($msg->getAdouble(), 0., 'adouble should be set to default value'); + a($msg->hasAdouble(), false, 'adouble shoult not be set'); + a($msg->getAint64(), 0, 'aint64 should be set to default value'); + a($msg->hasAint64(), false, 'aint64 shoult not be set'); + a($msg->getAbool(), false, 'abool should be set to default value'); + a($msg->hasAbool(), false, 'abool shoult not be set'); + a($msg->getAstring(), "", 'astring should be set to default value'); + a($msg->hasAstring(), false, 'astring shoult not be set'); + a($msg->getAbytes(), "", 'abytes should be set to default value'); + a($msg->hasAbytes(), false, 'abytes shoult not be set'); + + a($msg->getAnenum(), 0, 'anenum should be set to default value'); + a($msg->hasAnenum(), false, 'anenum shoult not be set'); + + a($msg->getAmsg(), null, 'adouble should be set to default value'); + a($msg->hasAmsg(), false, 'adouble shoult not be set'); + a($msg->getAnany(), null, 'anany should be set to default value'); + a($msg->hasAnany(), false, 'anany shoult not be set'); + echo("PASSED\n"); + + echo("Testing optional proto3 proto with only default values: "); + $msg = new \baz\optional_proto3(); + Protobuf\Unmarshal(file_get_contents('generated/test/default_optional_proto3.pb.bin'), $msg); + a($msg->getAdouble(), 0., 'adouble should be set to default value'); + a($msg->hasAdouble(), true, 'adouble should be set'); + a($msg->getAint64(), 0, 'aint64 should be set to default value'); + a($msg->hasAint64(), true, 'aint64 should be set'); + a($msg->getAbool(), false, 'abool should be set to default value'); + a($msg->hasAbool(), true, 'abool should be set'); + a($msg->getAstring(), "", 'astring should be set to default value'); + a($msg->hasAstring(), true, 'astring should be set'); + a($msg->getAbytes(), "", 'abytes should be set to default value'); + a($msg->hasAbytes(), true, 'abytes should be set'); + + a($msg->getAnenum(), 0, 'anenum should be set to default value'); + a($msg->hasAnenum(), true, 'anenum should be set'); + + a($msg->getAmsg()?->astring, "", 'amsg should be set to default value'); + a($msg->hasAmsg(), true, 'amsg should be set'); + a($msg->getAnany()?->value, "", 'anany should be set to default value'); + a($msg->hasAnany(), true, 'anany should be set'); + echo("PASSED\n"); + + echo("Testing optional proto3 proto with only custom non-default values: "); + $msg = new \baz\optional_proto3(); + Protobuf\Unmarshal(file_get_contents('generated/test/custom_optional_proto3.pb.bin'), $msg); + a($msg->getAdouble(), 3.14, 'adouble should be set'); + a($msg->hasAdouble(), true, 'adouble should be set'); + a($msg->getAint64(), 1234, 'aint64 should be set'); + a($msg->hasAint64(), true, 'aint64 should be set'); + a($msg->getAbool(), true, 'abool should be set'); + a($msg->hasAbool(), true, 'abool should be set'); + a($msg->getAstring(), "string", 'astring should be set'); + a($msg->hasAstring(), true, 'astring should be set'); + a($msg->getAbytes(), "bytes", 'abytes should be set'); + a($msg->hasAbytes(), true, 'abytes should be set'); + + a($msg->getAnenum(), 10, 'anenum should be set'); + a($msg->hasAnenum(), true, 'anenum should be set'); + + a($msg->getAmsg()?->astring, "inner_string", 'amsg should be set'); + a($msg->hasAmsg(), true, 'amsg should be set'); + a($msg->getAnany()?->value, "any_bytes", 'anany should be set'); + a($msg->hasAnany(), true, 'anany should be set'); + echo("PASSED\n"); + + echo("Testing JSON decoding: "); + $msg = new \baz\optional_proto3(); + Protobuf\UnmarshalJson(file_get_contents('test/mixed_optional_proto3.pb.json'), $msg); + a($msg->getAdouble(), 3.14, 'adouble should be set'); + a($msg->hasAdouble(), true, 'adouble should be set'); + a($msg->getAint64(), 1234, 'aint64 should be set'); + a($msg->hasAint64(), true, 'aint64 should be set'); + a($msg->getAbool(), false, 'abool should be set'); + a($msg->hasAbool(), true, 'abool should be set'); + a($msg->getAstring(), "", 'astring should be set'); + a($msg->hasAstring(), false, 'astring should be set'); + // TODO: We are storing some bad bytes during JSON decoding. + //a($msg->getAbytes(), "bytes", 'abytes should be set'); + a($msg->hasAbytes(), true, 'abytes should be set'); + + a($msg->getAnenum(), 10, 'anenum should be set'); + a($msg->hasAnenum(), true, 'anenum should be set'); + + a($msg->getAmsg()?->astring, "inner_string", 'amsg should be set'); + a($msg->hasAmsg(), true, 'amsg should be set'); + // TODO: We are storing some bad bytes during JSON decoding. + //a($msg->getAnany()->value, "any_bytes", 'anany should be set'); + a($msg->hasAnany(), true, 'anany should be set'); + echo("PASSED\n"); + } + function testLoopbackService(): void { $cli = new \foo\bar\ExampleServiceClient(new Grpc\LoopbackInvoker( \foo\bar\ExampleServiceServiceDescriptor(new ServerImpl()),