diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000000..d853702a11 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,16 @@ +# GitHub Action to automate the identification of common misspellings in text files. +# https://github.com/codespell-project/actions-codespell +# https://github.com/codespell-project/codespell +name: codespell +on: [push, pull_request] +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: codespell-project/actions-codespell@master + with: + check_filenames: true + skip: ./.git,./conformance/third_party,*.snk,*.pb,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal + ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" diff --git a/.gitignore b/.gitignore index a7349c2aa8..e06aedea6b 100644 --- a/.gitignore +++ b/.gitignore @@ -104,7 +104,7 @@ build_msvc # needed to trigger "pod install" to rerun the preinstall commands. Pods/ -# Comformance test output +# Conformance test output conformance/.libs/ conformance/com/ conformance/conformance-cpp @@ -137,19 +137,24 @@ conformance/*.class # php test output composer.lock +php/tests/.phpunit.result.cache php/tests/generated/ php/tests/old_protoc +php/tests/phpunit-9.phar php/tests/protobuf/ php/tests/core php/tests/vgcore* php/tests/multirequest.result php/tests/nohup.out +php/tests/.phpunit.result.cache +php/tests/phpunit-* php/ext/google/protobuf/.libs/ php/ext/google/protobuf/Makefile.fragments php/ext/google/protobuf/Makefile.global php/ext/google/protobuf/Makefile.objects php/ext/google/protobuf/acinclude.m4 php/ext/google/protobuf/build/ +php/ext/google/protobuf/bundled_php.c php/ext/google/protobuf/config.h php/ext/google/protobuf/config.h.in~ php/ext/google/protobuf/config.nice diff --git a/BUILD b/BUILD index 224c8fce19..f3fd3f4606 100644 --- a/BUILD +++ b/BUILD @@ -954,96 +954,13 @@ proto_lang_toolchain( alias( name = "objectivec", - actual = ":protobuf_objc", + actual = "//objectivec", visibility = ["//visibility:public"], ) -objc_library( +alias( name = "protobuf_objc", - hdrs = [ - "objectivec/GPBAny.pbobjc.h", - "objectivec/GPBApi.pbobjc.h", - "objectivec/GPBDuration.pbobjc.h", - "objectivec/GPBEmpty.pbobjc.h", - "objectivec/GPBFieldMask.pbobjc.h", - "objectivec/GPBSourceContext.pbobjc.h", - "objectivec/GPBStruct.pbobjc.h", - "objectivec/GPBTimestamp.pbobjc.h", - "objectivec/GPBType.pbobjc.h", - "objectivec/GPBWrappers.pbobjc.h", - "objectivec/GPBArray.h", - "objectivec/GPBBootstrap.h", - "objectivec/GPBCodedInputStream.h", - "objectivec/GPBCodedOutputStream.h", - "objectivec/GPBDescriptor.h", - "objectivec/GPBDictionary.h", - "objectivec/GPBExtensionInternals.h", - "objectivec/GPBExtensionRegistry.h", - "objectivec/GPBMessage.h", - "objectivec/GPBProtocolBuffers.h", - "objectivec/GPBProtocolBuffers_RuntimeSupport.h", - "objectivec/GPBRootObject.h", - "objectivec/GPBRuntimeTypes.h", - "objectivec/GPBUnknownField.h", - "objectivec/GPBUnknownFieldSet.h", - "objectivec/GPBUtilities.h", - "objectivec/GPBWellKnownTypes.h", - "objectivec/GPBWireFormat.h", - "objectivec/google/protobuf/Any.pbobjc.h", - "objectivec/google/protobuf/Api.pbobjc.h", - "objectivec/google/protobuf/Duration.pbobjc.h", - "objectivec/google/protobuf/Empty.pbobjc.h", - "objectivec/google/protobuf/FieldMask.pbobjc.h", - "objectivec/google/protobuf/SourceContext.pbobjc.h", - "objectivec/google/protobuf/Struct.pbobjc.h", - "objectivec/google/protobuf/Timestamp.pbobjc.h", - "objectivec/google/protobuf/Type.pbobjc.h", - "objectivec/google/protobuf/Wrappers.pbobjc.h", - # Package private headers, but exposed because the generated sources - # need to use them. - "objectivec/GPBArray_PackagePrivate.h", - "objectivec/GPBCodedInputStream_PackagePrivate.h", - "objectivec/GPBCodedOutputStream_PackagePrivate.h", - "objectivec/GPBDescriptor_PackagePrivate.h", - "objectivec/GPBDictionary_PackagePrivate.h", - "objectivec/GPBMessage_PackagePrivate.h", - "objectivec/GPBRootObject_PackagePrivate.h", - "objectivec/GPBUnknownFieldSet_PackagePrivate.h", - "objectivec/GPBUnknownField_PackagePrivate.h", - "objectivec/GPBUtilities_PackagePrivate.h", - ], - copts = [ - "-Wno-vla", - ], - includes = [ - "objectivec", - ], - non_arc_srcs = [ - "objectivec/GPBAny.pbobjc.m", - "objectivec/GPBApi.pbobjc.m", - "objectivec/GPBDuration.pbobjc.m", - "objectivec/GPBEmpty.pbobjc.m", - "objectivec/GPBFieldMask.pbobjc.m", - "objectivec/GPBSourceContext.pbobjc.m", - "objectivec/GPBStruct.pbobjc.m", - "objectivec/GPBTimestamp.pbobjc.m", - "objectivec/GPBType.pbobjc.m", - "objectivec/GPBWrappers.pbobjc.m", - "objectivec/GPBArray.m", - "objectivec/GPBCodedInputStream.m", - "objectivec/GPBCodedOutputStream.m", - "objectivec/GPBDescriptor.m", - "objectivec/GPBDictionary.m", - "objectivec/GPBExtensionInternals.m", - "objectivec/GPBExtensionRegistry.m", - "objectivec/GPBMessage.m", - "objectivec/GPBRootObject.m", - "objectivec/GPBUnknownField.m", - "objectivec/GPBUnknownFieldSet.m", - "objectivec/GPBUtilities.m", - "objectivec/GPBWellKnownTypes.m", - "objectivec/GPBWireFormat.m", - ], + actual = "//objectivec", visibility = ["//visibility:public"], ) diff --git a/CHANGES.txt b/CHANGES.txt index 6d77428d7d..76910c4d0c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -Unreleased Changes +2020-07-14 version 3.13.0-rc1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) C++: * Removed deprecated unsafe arena string accessors @@ -37,10 +37,19 @@ Unreleased Changes type internally. (#7351) * Add `ParseFrom(ReadOnlySequence)` method to enable GC friendly parsing with reduced allocations and buffer copies. (#7351) + * Add support for serialization directly to a `IBufferWriter` or + to a `Span` to enable GC friendly serialization. + The new API is available as extension methods on the `IMessage` type. (#7576) * Add `GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE` define to make generated code compatible with old C# compilers (pre-roslyn compilers from .NET framework and old versions of mono) that do not support - ref structs. (#7490) + ref structs. Users that are still on a legacy stack that does + not support C# 7.2 compiler might need to use the new define + in their projects to be able to build the newly generated code. (#7490) + * Due to the major overhaul of parsing and serialization internals (#7351 and #7576), + it is recommended to regenerate your generated code to achieve the best + performance (the legacy generated code will still work, but might incur + a slight performance penalty). 2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) diff --git a/Protobuf.podspec b/Protobuf.podspec index 3b7a716761..22e7ce3003 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,7 +5,7 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.12.3' + s.version = '3.13.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/protocolbuffers/protobuf' s.license = '3-Clause BSD License' diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index 6bf86a2770..bbba6071f7 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -12,6 +12,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.cc ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc + ${protobuf_source_dir}/src/google/protobuf/map.cc ${protobuf_source_dir}/src/google/protobuf/message_lite.cc ${protobuf_source_dir}/src/google/protobuf/parse_context.cc ${protobuf_source_dir}/src/google/protobuf/repeated_field.cc diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt index 1c7f92bc92..d51a75dc36 100644 --- a/conformance/failure_list_php.txt +++ b/conformance/failure_list_php.txt @@ -6,62 +6,6 @@ Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto3.JsonInput.DoubleFieldTooSmall Required.Proto3.JsonInput.FloatFieldTooLarge diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index cfed9f6d4d..63c7e8a024 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,58 +1,2 @@ Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/failure_list_php_c_32.txt b/conformance/failure_list_php_c_32.txt index cfed9f6d4d..63c7e8a024 100644 --- a/conformance/failure_list_php_c_32.txt +++ b/conformance/failure_list_php_c_32.txt @@ -1,58 +1,2 @@ Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/third_party/jsoncpp/json.h b/conformance/third_party/jsoncpp/json.h index 5639c92451..373ec98bde 100644 --- a/conformance/third_party/jsoncpp/json.h +++ b/conformance/third_party/jsoncpp/json.h @@ -1371,7 +1371,7 @@ public: */ std::string getFormattedErrorMessages() const; - /** \brief Returns a vector of structured errors encounted while parsing. + /** \brief Returns a vector of structured errors encountered while parsing. * \return A (possibly empty) vector of StructuredError objects. Currently * only one error can be returned, but the caller should tolerate * multiple @@ -1867,7 +1867,7 @@ private: * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -1928,7 +1928,7 @@ private: * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their #CommentPlacement. * * \param indentation Each level will be indented by this amount extra. diff --git a/conformance/third_party/jsoncpp/jsoncpp.cpp b/conformance/third_party/jsoncpp/jsoncpp.cpp index d313d0563c..78919eac0f 100644 --- a/conformance/third_party/jsoncpp/jsoncpp.cpp +++ b/conformance/third_party/jsoncpp/jsoncpp.cpp @@ -142,7 +142,7 @@ enum { typedef char UIntToStringBuffer[uintToStringBufferSize]; /** Converts an unsigned integer to string. - * @param value Unsigned interger to convert to string + * @param value Unsigned integer to convert to string * @param current Input/Output string buffer. * Must have at least uintToStringBufferSize chars free. */ diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index d0c088f2a1..019f054472 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.12.3 + 3.13.0 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/master/LICENSE diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index 49a5a42665..b663138d10 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh @@ -45,6 +45,7 @@ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf \ # and old_extensions2.proto, which are generated with an older version # of protoc. $PROTOC -Isrc -Icsharp/protos \ + --experimental_allow_proto3_optional \ --csharp_out=csharp/src/Google.Protobuf.Test.TestProtos \ --descriptor_set_out=csharp/src/Google.Protobuf.Test/testprotos.pb \ --include_source_info \ diff --git a/csharp/protos/unittest_issues.proto b/csharp/protos/unittest_issues.proto index ef40d75fce..388998f0a0 100644 --- a/csharp/protos/unittest_issues.proto +++ b/csharp/protos/unittest_issues.proto @@ -151,3 +151,8 @@ message NullValueOutsideStruct { message NullValueNotInOneof { google.protobuf.NullValue null_value = 2; } + +message MixedRegularAndOptional { + string regular_field = 1; + optional string optional_field = 2; +} diff --git a/csharp/src/AddressBook/Program.cs b/csharp/src/AddressBook/Program.cs index ff7b9c085e..de4867a0ce 100644 --- a/csharp/src/AddressBook/Program.cs +++ b/csharp/src/AddressBook/Program.cs @@ -37,7 +37,7 @@ namespace Google.Protobuf.Examples.AddressBook /// /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour /// to individual actions. Each action has its own Main method, so that it can be used as an - /// invidual complete program. + /// individual complete program. /// internal class Program { diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs index e09191a65c..4377cf3a19 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs @@ -52,11 +52,13 @@ namespace UnitTest.Issues.TestProtos { "bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl", "LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v", "dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1", - "Zi5OdWxsVmFsdWUqVQoMTmVnYXRpdmVFbnVtEhYKEk5FR0FUSVZFX0VOVU1f", - "WkVSTxAAEhYKCUZpdmVCZWxvdxD7//////////8BEhUKCE1pbnVzT25lEP//", - "/////////wEqLgoORGVwcmVjYXRlZEVudW0SEwoPREVQUkVDQVRFRF9aRVJP", - "EAASBwoDb25lEAFCHaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZw", - "cm90bzM=")); + "Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn", + "dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB", + "QhEKD19vcHRpb25hbF9maWVsZCpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJ", + "VkVfRU5VTV9aRVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWlu", + "dXNPbmUQ////////////ASouCg5EZXByZWNhdGVkRW51bRITCg9ERVBSRUNB", + "VEVEX1pFUk8QABIHCgNvbmUQAUIdqgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQ", + "cm90b3NiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -70,7 +72,8 @@ namespace UnitTest.Issues.TestProtos { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueOutsideStruct), global::UnitTest.Issues.TestProtos.NullValueOutsideStruct.Parser, new[]{ "StringValue", "NullValue" }, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null) })); } #endregion @@ -3304,6 +3307,224 @@ namespace UnitTest.Issues.TestProtos { } + public sealed partial class MixedRegularAndOptional : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MixedRegularAndOptional()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[11]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional(MixedRegularAndOptional other) : this() { + regularField_ = other.regularField_; + optionalField_ = other.optionalField_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional Clone() { + return new MixedRegularAndOptional(this); + } + + /// Field number for the "regular_field" field. + public const int RegularFieldFieldNumber = 1; + private string regularField_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string RegularField { + get { return regularField_; } + set { + regularField_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "optional_field" field. + public const int OptionalFieldFieldNumber = 2; + private string optionalField_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string OptionalField { + get { return optionalField_ ?? ""; } + set { + optionalField_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "optional_field" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalField { + get { return optionalField_ != null; } + } + /// Clears the value of the "optional_field" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalField() { + optionalField_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as MixedRegularAndOptional); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(MixedRegularAndOptional other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (RegularField != other.RegularField) return false; + if (OptionalField != other.OptionalField) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (RegularField.Length != 0) hash ^= RegularField.GetHashCode(); + if (HasOptionalField) hash ^= OptionalField.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (RegularField.Length != 0) { + output.WriteRawTag(10); + output.WriteString(RegularField); + } + if (HasOptionalField) { + output.WriteRawTag(18); + output.WriteString(OptionalField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (RegularField.Length != 0) { + output.WriteRawTag(10); + output.WriteString(RegularField); + } + if (HasOptionalField) { + output.WriteRawTag(18); + output.WriteString(OptionalField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (RegularField.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(RegularField); + } + if (HasOptionalField) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalField); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(MixedRegularAndOptional other) { + if (other == null) { + return; + } + if (other.RegularField.Length != 0) { + RegularField = other.RegularField; + } + if (other.HasOptionalField) { + OptionalField = other.OptionalField; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + RegularField = input.ReadString(); + break; + } + case 18: { + OptionalField = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + RegularField = input.ReadString(); + break; + } + case 18: { + OptionalField = input.ReadString(); + break; + } + } + } + } + #endif + + } + #endregion } diff --git a/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs index 8e42d13dab..5b9913b290 100644 --- a/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs +++ b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs @@ -60,7 +60,7 @@ namespace Google.Protobuf.Buffers } /// - /// Userful for testing writing to buffer writer with a lot of small segments. + /// Useful for testing writing to buffer writer with a lot of small segments. /// If set, it limits the max number of bytes by which the buffer grows by at once. /// public int? MaxGrowBy { get; set; } diff --git a/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/csharp/src/Google.Protobuf.Test/IssuesTest.cs index 941bce0160..2904c461df 100644 --- a/csharp/src/Google.Protobuf.Test/IssuesTest.cs +++ b/csharp/src/Google.Protobuf.Test/IssuesTest.cs @@ -108,7 +108,7 @@ namespace Google.Protobuf // we still must read the tag correctly, even though the tag is at the very end of our limited input // (which is a corner case and will most likely result in an error when trying to read value of the field - // decribed by this tag, but it would be a logical error not to read the tag that's actually present). + // described by this tag, but it would be a logical error not to read the tag that's actually present). // See https://github.com/protocolbuffers/protobuf/pull/7289 cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint)); } diff --git a/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs index 20c1846da4..46a8c57a78 100644 --- a/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs +++ b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs @@ -34,6 +34,7 @@ using NUnit.Framework; using ProtobufUnittest; using System; using System.IO; +using UnitTest.Issues.TestProtos; namespace Google.Protobuf.Test { @@ -139,5 +140,14 @@ namespace Google.Protobuf.Test Assert.IsTrue(message1.Equals(message2)); message1.ClearOptionalInt32(); } + + [Test] + public void MixedFields() + { + var descriptor = MixedRegularAndOptional.Descriptor; + Assert.AreEqual(1, descriptor.Oneofs.Count); + Assert.AreEqual(0, descriptor.RealOneofCount); + Assert.True(descriptor.Oneofs[0].IsSynthetic); + } } } diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index bde0dae504..bae05e08fb 100644 Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs index 74dc865e9d..2a52ae58be 100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs @@ -269,7 +269,7 @@ namespace Google.Protobuf } /// - /// Retuns the byte at the given index. + /// Returns the byte at the given index. /// public byte this[int index] { diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index 4050cbec8c..b09f96ce28 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -652,7 +652,7 @@ namespace Google.Protobuf /// /// Called when buffer is empty to read more bytes from the - /// input. If is true, RefillBuffer() gurantees that + /// input. If is true, RefillBuffer() guarantees that /// either there will be at least one byte in the buffer when it returns /// or it will throw an exception. If is false, /// RefillBuffer() returns false if no more bytes were available. diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index db86da520e..082a398bfe 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -4,8 +4,7 @@ C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.12.2 - 3.12.3 + 3.13.0 7.2 Google Inc. diff --git a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs index 4e040c17ea..7523426dc5 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs @@ -63,7 +63,7 @@ namespace Google.Protobuf.Reflection internal static OneofAccessor ForSyntheticOneof(OneofDescriptor descriptor) { // Note: descriptor.Fields will be null when this method is called, because we haven't - // cross-linked yet. But by the time the delgates are called by user code, all will be + // cross-linked yet. But by the time the delegates are called by user code, all will be // well. (That's why we capture the descriptor itself rather than a field.) return new OneofAccessor(descriptor, message => descriptor.Fields[0].Accessor.HasValue(message) ? descriptor.Fields[0].FieldNumber : 0, diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs index 0df4f534b2..b41d520515 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs @@ -59,7 +59,7 @@ namespace Google.Protobuf.Reflection // It's useful to determine whether or not this is a synthetic oneof before cross-linking. That means // diving into the proto directly rather than using FieldDescriptor, but that's okay. - var firstFieldInOneof = parent.Proto.Field.FirstOrDefault(fieldProto => fieldProto.OneofIndex == index); + var firstFieldInOneof = parent.Proto.Field.FirstOrDefault(fieldProto => fieldProto.HasOneofIndex && fieldProto.OneofIndex == index); IsSynthetic = firstFieldInOneof?.Proto3Optional ?? false; accessor = CreateAccessor(clrName); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index c75ef0f9a1..2fb1b4d164 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -91,7 +91,15 @@ namespace Google.Protobuf.WellKnownTypes { /// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) /// .setNanos((int) ((millis % 1000) * 1000000)).build(); /// - /// Example 5: Compute Timestamp from current time in Python. + /// Example 5: Compute Timestamp from Java `Instant.now()`. + /// + /// Instant now = Instant.now(); + /// + /// Timestamp timestamp = + /// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + /// .setNanos(now.getNano()).build(); + /// + /// Example 6: Compute Timestamp from current time in Python. /// /// timestamp = Timestamp() /// timestamp.GetCurrentTime() diff --git a/docs/csharp/proto2.md b/docs/csharp/proto2.md index 0d9159de73..53fc43c7eb 100644 --- a/docs/csharp/proto2.md +++ b/docs/csharp/proto2.md @@ -97,7 +97,7 @@ foo.GetOrInitializeExtension(RepeatedFooExt).Add(new Baz()); ### Message initialization -Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforseen errors at runtime if the incorrect method is used. +Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforeseen errors at runtime if the incorrect method is used. However, in this implementation, parsers and input streams don't check messages for initialization on their own and throw errors. Instead it's up to you to handle messages with missing required fields in whatever way you see fit. Checking message initialization can be done manually via the `IsInitialized` extension method in `MessageExtensions`. diff --git a/docs/field_presence.md b/docs/field_presence.md index 4ce778552b..dc16292c85 100644 --- a/docs/field_presence.md +++ b/docs/field_presence.md @@ -127,7 +127,7 @@ The _no presence_ serialization discipline results in visible differences from t ### Considerations for merging -Under the _no presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf's API merging functions). This is because default values are skipped, simliar to the _no presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message. +Under the _no presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf's API merging functions). This is because default values are skipped, similar to the _no presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message. The difference in merging behavior has further implications for protocols which rely on partial "patch" updates. If field presence is not tracked, then an update patch alone cannot represent an update to the default value, because only non-default values are merged-from. diff --git a/docs/implementing_proto3_presence.md b/docs/implementing_proto3_presence.md index fae2eb589a..73f21a3829 100644 --- a/docs/implementing_proto3_presence.md +++ b/docs/implementing_proto3_presence.md @@ -13,7 +13,7 @@ optional fields. First-party code generators developed by Google are being updated already. However third-party code generators will need to be updated independently by their authors. This includes: -- implementations of Protocol Buffers for other languges. +- implementations of Protocol Buffers for other languages. - alternate implementations of Protocol Buffers that target specialized use cases. - RPC code generators that create generated APIs for service calls. diff --git a/docs/options.md b/docs/options.md index df6b88c033..fd1e813797 100644 --- a/docs/options.md +++ b/docs/options.md @@ -244,3 +244,7 @@ with info about your project (name and website) so we can add an entry for you. 1. ADLINK EdgeSDK * Website: https://www.adlinktech.com/en/Edge-SDK-IoT * Extensions: 1086 + +1. Wire wire_package + * Website: https://square.github.io/wire/ + * Extensions: 1087 diff --git a/docs/third_party.md b/docs/third_party.md index c1726a0f17..b9c66c02f1 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -26,8 +26,8 @@ These are projects we know about implementing Protocol Buffers for other program * Clojure: http://github.com/ninjudd/clojure-protobuf * Clojure: https://github.com/clojusc/protobuf * Clojure: https://protojure.github.io -* Common Lisp: http://github.com/ndantam/s-protobuf * Common Lisp: http://github.com/brown/protobuf +* Common Lisp: http://github.com/qitab/cl-protobuf * D: https://github.com/dcarp/protobuf-d * D: https://github.com/msoucy/dproto * D: https://github.com/opticron/ProtocolBuffer @@ -62,6 +62,8 @@ These are projects we know about implementing Protocol Buffers for other program * Javascript: https://github.com/dcodeIO/ProtoBuf.js * Javascript: http://code.google.com/p/protobuf-for-node/ * Javascript: http://code.google.com/p/protostuff/ +* Javascript: https://github.com/seishun/node-protoc-plugin (Node.js port of plugin.h) +* Javascript: https://github.com/seishun/node-protoc-gen-javascript (Node.js port of the Google-official implementation) * Julia: https://github.com/tanmaykm/ProtoBuf.jl * Kotlin: https://github.com/marcoferrer/kroto-plus * Kotlin: https://github.com/Kotlin/kotlinx.serialization @@ -154,7 +156,7 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [Alternate encodings (JSON, XML, HTML) for Java protobufs](http://code.google.com/p/protobuf-java-format/) * [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec) * [Editor for serialized protobufs](http://code.google.com/p/protobufeditor/) -* [Intellij IDEA plugin](http://github.com/nnmatveev/idea-plugin-protobuf) +* [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor) * [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle) * [Oracle PL SQL plugin](http://code.google.com/p/protocol-buffer-plsql/) * [Eclipse editor for protobuf (from Google)](http://code.google.com/p/protobuf-dt/) @@ -184,3 +186,9 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [Protocol Buffer property-based testing utility and example message generator (Python / Hypothesis)](https://github.com/CurataEng/hypothesis-protobuf) * [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock) * [Optional GRPC - GRPC for testable microservices (Python)](https://github.com/mattpaletta/optional-grpc.git) +* [Protobuf Parser - Yet another Go package which parses a Protocol Buffer file (proto2+proto3)](https://github.com/yoheimuta/go-protoparser) +* [Protolint - A tool to enforce Protocol Buffer style and conventions.](https://github.com/yoheimuta/protolint) + * [vscode-protolint: A protobuf linter for visual studio code](https://github.com/plexsystems/vscode-protolint) + * [intellij-protolint: A protobuf linter for JetBrains IDEs](https://github.com/yoheimuta/intellij-protolint) + * [vim-protolint: A protobuf linter for Vim](https://github.com/yoheimuta/vim-protolint) +* [super-linter: Protocol Buffer lint as GitHub Action](https://github.com/github/super-linter) diff --git a/java/README.md b/java/README.md index c4e8e20de5..dea9e763f2 100644 --- a/java/README.md +++ b/java/README.md @@ -47,7 +47,7 @@ If you are using Gradle, add the following to your `build.gradle` file's depende ``` compile 'com.google.protobuf:protobuf-java:3.11.0' ``` -Again, be sure to check that the version number maches (or is newer than) the version number of protoc that you are using. +Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using. ### Use Java Protocol Buffers on Android @@ -68,7 +68,7 @@ how to use them. Most users should follow the instructions above to use protobuf Java runtime. If you are contributing code to protobuf or want to use a protobuf version -that hasn't been officially released yet, you can folllow the instructions +that hasn't been officially released yet, you can follow the instructions below to build protobuf from source code. ### Build from Source - With Maven diff --git a/java/bom/pom.xml b/java/bom/pom.xml index ff2d106764..3642783f6a 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.12.3 + 3.13.0 pom Protocol Buffers [BOM] diff --git a/java/core/pom.xml b/java/core/pom.xml index b2b0b0386e..3509163b08 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.12.3 + 3.13.0 protobuf-java diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java index 63dda6b9f2..8beebba24d 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -328,20 +328,6 @@ public final class DynamicMessage extends AbstractMessage { this.fields = FieldSet.newFieldSet(); this.unknownFields = UnknownFieldSet.getDefaultInstance(); this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()]; - // A MapEntry has all of its fields present at all times. - if (type.getOptions().getMapEntry()) { - populateMapEntry(); - } - } - - private void populateMapEntry() { - for (FieldDescriptor field : type.getFields()) { - if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - fields.setField(field, getDefaultInstance(field.getMessageType())); - } else { - fields.setField(field, field.getDefaultValue()); - } - } } // --------------------------------------------------------------- @@ -354,10 +340,6 @@ public final class DynamicMessage extends AbstractMessage { } else { fields.clear(); } - // A MapEntry has all of its fields present at all times. - if (type.getOptions().getMapEntry()) { - populateMapEntry(); - } unknownFields = UnknownFieldSet.getDefaultInstance(); return this; } @@ -423,6 +405,19 @@ public final class DynamicMessage extends AbstractMessage { @Override public DynamicMessage buildPartial() { + // Set default values for all fields in a MapEntry. + if (type.getOptions().getMapEntry()) { + for (FieldDescriptor field : type.getFields()) { + if (field.isOptional() && !fields.hasField(field)) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + fields.setField(field, getDefaultInstance(field.getMessageType())); + } else { + fields.setField(field, field.getDefaultValue()); + } + } + } + } + fields.makeImmutable(); DynamicMessage result = new DynamicMessage( diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java index 139e55a971..28879d7785 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java @@ -1402,8 +1402,10 @@ final class MessageSchema implements Schema { if (!isOneofPresent(other, number, pos)) { return; } - - Object mine = UnsafeUtil.getObject(message, offset); + Object mine = null; + if (isOneofPresent(message, number, pos)) { + mine = UnsafeUtil.getObject(message, offset); + } Object theirs = UnsafeUtil.getObject(other, offset); if (mine != null && theirs != null) { Object merged = Internal.mergeMessage(mine, theirs); diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index bec9623fe8..7f744ddba7 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -1661,7 +1661,7 @@ public final class TextFormat { throws IOException { // Read the entire input to a String then parse that. - // If StreamTokenizer were not quite so crippled, or if there were a kind + // If StreamTokenizer was not so limited, or if there were a kind // of Reader that could read in chunks that match some particular regex, // or if we wanted to write a custom Reader to tokenize our stream, then // we would not have to read to one big String. Alas, none of these is diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index a9a884e196..e229facace 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -1478,11 +1478,23 @@ public class TextFormatTest extends TestCase { // With overwrite forbidden, same behavior. // TODO(b/29122459): Expect parse exception here. TestMap.Builder builder = TestMap.newBuilder(); - defaultParser.merge(text, builder); + parserWithOverwriteForbidden.merge(text, builder); TestMap map = builder.build(); assertEquals(2, map.getInt32ToInt32Field().size()); assertEquals(30, map.getInt32ToInt32Field().get(1).intValue()); } + + { + // With overwrite forbidden and a dynamic message, same behavior. + // TODO(b/29122459): Expect parse exception here. + Message.Builder builder = DynamicMessage.newBuilder(TestMap.getDescriptor()); + parserWithOverwriteForbidden.merge(text, builder); + TestMap map = + TestMap.parseFrom( + builder.build().toByteString(), ExtensionRegistryLite.getEmptyRegistry()); + assertEquals(2, map.getInt32ToInt32Field().size()); + assertEquals(30, map.getInt32ToInt32Field().get(1).intValue()); + } } // ======================================================================= diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 49686cd7ad..779eacc637 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.12.3 + 3.13.0 protobuf-javalite @@ -52,6 +52,7 @@ google/protobuf/any.proto google/protobuf/api.proto + google/protobuf/duration.proto google/protobuf/empty.proto google/protobuf/field_mask.proto google/protobuf/source_context.proto diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java index 3e39bc7c8b..140df7270f 100644 --- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java @@ -42,6 +42,7 @@ import com.google.protobuf.UnittestLite.TestAllExtensionsLite; import com.google.protobuf.UnittestLite.TestAllTypesLite; import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum; import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage; +import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2; import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase; import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup; import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup; @@ -1354,6 +1355,45 @@ public class LiteTest extends TestCase { assertEquals(message.getSerializedSize() * 2, result.getSerializedSize()); } + public void testMergeFrom_differentFieldsSetWithinOneField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofNestedMessage2(NestedMessage2.newBuilder().setDd(3)) + .build()) + .build(); + + assertToStringEquals("oneof_nested_message2 {\n dd: 3\n}", result); + } + + public void testMergeFrom_differentFieldsOfSameTypeSetWithinOneField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofLazyNestedMessage(NestedMessage.newBuilder().setCc(3)) + .build()) + .build(); + + assertToStringEquals("oneof_lazy_nested_message {\n cc: 3\n}", result); + } + + public void testMergeFrom_sameFieldSetWithinOneofField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setCc(4)) + .build()) + .build(); + + assertToStringEquals("oneof_nested_message {\n bb: 2\n cc: 4\n}", result); + } + public void testToStringDefaultInstance() throws Exception { assertToStringEquals("", TestAllTypesLite.getDefaultInstance()); } diff --git a/java/pom.xml b/java/pom.xml index 0a813e02dc..bb91146fd2 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.12.3 + 3.13.0 pom Protocol Buffers [Parent] diff --git a/java/util/BUILD b/java/util/BUILD index cfdb28e2e1..71f73bab10 100644 --- a/java/util/BUILD +++ b/java/util/BUILD @@ -5,10 +5,6 @@ java_library( srcs = glob([ "src/main/java/com/google/protobuf/util/*.java", ]), - javacopts = [ - "-source 7", - "-target 7", - ], visibility = ["//visibility:public"], deps = [ "//external:error_prone_annotations", diff --git a/java/util/pom.xml b/java/util/pom.xml index daa123a944..54dcc86907 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.12.3 + 3.13.0 protobuf-java-util diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index 67981435d1..cc3f5f658f 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -328,14 +328,13 @@ public class JsonFormat { /** * Create a new {@link Printer} that will sort the map keys in the JSON output. * - * Use of this modifier is discouraged, the generated JSON messages are equivalent - * with and without this option set, but there are some corner caseuse cases that - * demand a stable output, while order of map keys is otherwise arbitrary. + *

Use of this modifier is discouraged, the generated JSON messages are equivalent with and + * without this option set, but there are some corner use cases that demand a stable output, + * while order of map keys is otherwise arbitrary. * - * The generated order is not well-defined and should not be depended on, but - * it's stable. + *

The generated order is not well-defined and should not be depended on, but it's stable. * - * This new Printer clones all other configurations from the current {@link Printer}. + *

This new Printer clones all other configurations from the current {@link Printer}. */ public Printer sortingMapKeys() { return new Printer( diff --git a/js/experimental/runtime/kernel/kernel_test.js b/js/experimental/runtime/kernel/kernel_test.js index e72be4f3b6..eba7c4a55a 100644 --- a/js/experimental/runtime/kernel/kernel_test.js +++ b/js/experimental/runtime/kernel/kernel_test.js @@ -699,7 +699,7 @@ describe('Bytes access', () => { expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01)); expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); @@ -801,7 +801,7 @@ describe('Fixed32 access', () => { expect(accessor.getFixed32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); expect(accessor.getFixed32WithDefault(1)).toEqual(2); @@ -909,7 +909,7 @@ describe('Fixed64 access', () => { expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); @@ -1008,7 +1008,7 @@ describe('Float access', () => { expect(accessor.getFloatWithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF)); expect(accessor.getFloatWithDefault(1)).toEqual(-1); @@ -1110,7 +1110,7 @@ describe('Int32 access', () => { expect(accessor.getInt32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getInt32WithDefault(1)).toEqual(2); @@ -1207,7 +1207,7 @@ describe('Int64 access', () => { expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); @@ -1306,7 +1306,7 @@ describe('Sfixed32 access', () => { expect(accessor.getSfixed32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); expect(accessor.getSfixed32WithDefault(1)).toEqual(2); @@ -1404,7 +1404,7 @@ describe('Sfixed64 access', () => { expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); @@ -1502,7 +1502,7 @@ describe('Sint32 access', () => { expect(accessor.getSint32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); expect(accessor.getSint32WithDefault(1)).toEqual(1); @@ -1599,7 +1599,7 @@ describe('SInt64 access', () => { expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); @@ -1698,7 +1698,7 @@ describe('String access', () => { expect(accessor.getStringWithDefault(1)).toEqual('a'); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61)); expect(accessor.getStringWithDefault(1)).toEqual('a'); @@ -1789,7 +1789,7 @@ describe('Uint32 access', () => { expect(accessor.getUint32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getUint32WithDefault(1)).toEqual(2); @@ -1896,7 +1896,7 @@ describe('Uint64 access', () => { expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); @@ -1996,7 +1996,7 @@ describe('Double access', () => { }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)); diff --git a/js/experimental/runtime/kernel/tag_test.js b/js/experimental/runtime/kernel/tag_test.js index 04a6cb6668..35137bb247 100644 --- a/js/experimental/runtime/kernel/tag_test.js +++ b/js/experimental/runtime/kernel/tag_test.js @@ -95,12 +95,12 @@ describe('skipField', () => { it('skips group in group', () => { const buffer = createArrayBuffer( - 0x0B, // start outter + 0x0B, // start outer 0x10, 0x01, // field: 2, value: 1 0x0B, // start inner group 0x10, 0x01, // payload inner group 0x0C, // stop inner group - 0x0C // end outter + 0x0C // end outer ); const bufferDecoder = BufferDecoder.fromArrayBuffer(buffer); bufferDecoder.setCursor(1); diff --git a/kokoro/linux/dockerfile/test/php80/Dockerfile b/kokoro/linux/dockerfile/test/php80/Dockerfile new file mode 100644 index 0000000000..d6c9b4d273 --- /dev/null +++ b/kokoro/linux/dockerfile/test/php80/Dockerfile @@ -0,0 +1,96 @@ +FROM debian:jessie + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + re2c \ + sqlite3 \ + vim \ + libonig-dev \ + libsqlite3-dev \ + && apt-get clean + +# Install php dependencies +RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ + php5 \ + libcurl4-openssl-dev \ + libgmp-dev \ + libgmp3-dev \ + libssl-dev \ + libxml2-dev \ + unzip \ + zlib1g-dev \ + pkg-config \ + && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget https://ftp.gnu.org/gnu/bison/bison-3.0.1.tar.gz -O /var/local/bison-3.0.1.tar.gz +RUN cd /var/local \ + && tar -zxvf bison-3.0.1.tar.gz \ + && cd /var/local/bison-3.0.1 \ + && ./configure \ + && make \ + && make install + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer + +# Download php source code +RUN git clone https://github.com/php/php-src + +# php 8.0 +RUN cd php-src \ + && git checkout php-8.0.0alpha3 \ + && ./buildconf --force +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.0 \ + && make \ + && make install \ + && make clean +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --enable-maintainer-zts \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.0-zts \ + && make \ + && make install \ + && make clean + +RUN wget -O phpunit https://phar.phpunit.de/phpunit-9.phar \ + && chmod +x phpunit \ + && cp phpunit /usr/local/php-8.0/bin \ + && mv phpunit /usr/local/php-8.0-zts/bin + +# Install php dependencies +RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ + valgrind \ + && apt-get clean diff --git a/kokoro/linux/php80/build.sh b/kokoro/linux/php80/build.sh new file mode 100755 index 0000000000..6499b39af8 --- /dev/null +++ b/kokoro/linux/php80/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# This is the top-level script we give to Kokoro as the entry point for +# running the "pull request" project: +# +# This script selects a specific Dockerfile (for building a Docker image) and +# a script to run inside that image. Then we delegate to the general +# build_and_run_docker.sh script. + +# Change to repo root +cd $(dirname $0)/../../.. + +export DOCKERHUB_ORGANIZATION=protobuftesting +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php +export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh +export OUTPUT_DIR=testoutput +export TEST_SET="php8.0_all" +./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/php80/continuous.cfg b/kokoro/linux/php80/continuous.cfg new file mode 100644 index 0000000000..8426318bbe --- /dev/null +++ b/kokoro/linux/php80/continuous.cfg @@ -0,0 +1,11 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/linux/php80/build.sh" +timeout_mins: 120 + +action { + define_artifacts { + regex: "**/sponge_log.xml" + } +} diff --git a/kokoro/linux/php80/presubmit.cfg b/kokoro/linux/php80/presubmit.cfg new file mode 100644 index 0000000000..8426318bbe --- /dev/null +++ b/kokoro/linux/php80/presubmit.cfg @@ -0,0 +1,11 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/linux/php80/build.sh" +timeout_mins: 120 + +action { + define_artifacts { + regex: "**/sponge_log.xml" + } +} diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc index 18ce60b17f..830e7eee67 100755 --- a/kokoro/macos/prepare_build_macos_rc +++ b/kokoro/macos/prepare_build_macos_rc @@ -66,7 +66,7 @@ fi # Install Tox if [[ "${KOKORO_INSTALL_TOX:-}" == "yes" ]] ; then - sudo pip install tox==2.4.1 + sudo python3 -m pip install --upgrade pip tox fi ## diff --git a/kokoro/release/collect_all_artifacts.sh b/kokoro/release/collect_all_artifacts.sh index 3b7d7d4066..8f6e9db9a0 100755 --- a/kokoro/release/collect_all_artifacts.sh +++ b/kokoro/release/collect_all_artifacts.sh @@ -39,7 +39,7 @@ cp ${INPUT_ARTIFACTS_DIR}/build64/Release/protoc.exe protoc/windows_x64/protoc.e mkdir -p protoc/linux_x86 mkdir -p protoc/linux_x64 # Because of maven unrelated reasonse the linux protoc binaries have a dummy .exe extension. -# For the Google.Protobuf.Tools nuget, we don't want that expection, so we just remove it. +# For the Google.Protobuf.Tools nuget, we don't want that exception, so we just remove it. cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_32/protoc.exe protoc/linux_x86/protoc cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_64/protoc.exe protoc/linux_x64/protoc diff --git a/kokoro/release/python/macos/config.sh b/kokoro/release/python/macos/config.sh index 741988a6b5..1b0a302e4c 100644 --- a/kokoro/release/python/macos/config.sh +++ b/kokoro/release/python/macos/config.sh @@ -1,6 +1,25 @@ # Define custom utilities # Test for OSX with [ -n "$IS_OSX" ] +function remove_travis_ve_pip { + # Removing the system virtualenv or pip can be very problematic for + # macOS on Kokoro, so just leave them be. + :; +} + +function install_pip { + check_python + PIP_CMD="sudo $PYTHON_EXE -m pip${pip_args:+ $pip_args}" + $PIP_CMD install --upgrade pip +} + +function install_virtualenv { + check_python + check_pip + $PIP_CMD install --upgrade virtualenv + VIRTUALENV_CMD="$PYTHON_EXE -m virtualenv" +} + function pre_build { # Any stuff that you need to do before you start building the wheels # Runs in the root directory of this repository. diff --git a/objectivec/BUILD b/objectivec/BUILD new file mode 100644 index 0000000000..9f702ec95f --- /dev/null +++ b/objectivec/BUILD @@ -0,0 +1,90 @@ +load("@rules_cc//cc:defs.bzl", "objc_library") + +objc_library( + name = "objectivec", + hdrs = [ + "GPBAny.pbobjc.h", + "GPBApi.pbobjc.h", + "GPBDuration.pbobjc.h", + "GPBEmpty.pbobjc.h", + "GPBFieldMask.pbobjc.h", + "GPBSourceContext.pbobjc.h", + "GPBStruct.pbobjc.h", + "GPBTimestamp.pbobjc.h", + "GPBType.pbobjc.h", + "GPBWrappers.pbobjc.h", + "GPBArray.h", + "GPBBootstrap.h", + "GPBCodedInputStream.h", + "GPBCodedOutputStream.h", + "GPBDescriptor.h", + "GPBDictionary.h", + "GPBExtensionInternals.h", + "GPBExtensionRegistry.h", + "GPBMessage.h", + "GPBProtocolBuffers.h", + "GPBProtocolBuffers_RuntimeSupport.h", + "GPBRootObject.h", + "GPBRuntimeTypes.h", + "GPBUnknownField.h", + "GPBUnknownFieldSet.h", + "GPBUtilities.h", + "GPBWellKnownTypes.h", + "GPBWireFormat.h", + "google/protobuf/Any.pbobjc.h", + "google/protobuf/Api.pbobjc.h", + "google/protobuf/Duration.pbobjc.h", + "google/protobuf/Empty.pbobjc.h", + "google/protobuf/FieldMask.pbobjc.h", + "google/protobuf/SourceContext.pbobjc.h", + "google/protobuf/Struct.pbobjc.h", + "google/protobuf/Timestamp.pbobjc.h", + "google/protobuf/Type.pbobjc.h", + "google/protobuf/Wrappers.pbobjc.h", + # Package private headers, but exposed because the generated sources + # need to use them. + "GPBArray_PackagePrivate.h", + "GPBCodedInputStream_PackagePrivate.h", + "GPBCodedOutputStream_PackagePrivate.h", + "GPBDescriptor_PackagePrivate.h", + "GPBDictionary_PackagePrivate.h", + "GPBMessage_PackagePrivate.h", + "GPBRootObject_PackagePrivate.h", + "GPBUnknownFieldSet_PackagePrivate.h", + "GPBUnknownField_PackagePrivate.h", + "GPBUtilities_PackagePrivate.h", + ], + copts = [ + "-Wno-vla", + ], + includes = [ + ".", + ], + non_arc_srcs = [ + "GPBAny.pbobjc.m", + "GPBApi.pbobjc.m", + "GPBDuration.pbobjc.m", + "GPBEmpty.pbobjc.m", + "GPBFieldMask.pbobjc.m", + "GPBSourceContext.pbobjc.m", + "GPBStruct.pbobjc.m", + "GPBTimestamp.pbobjc.m", + "GPBType.pbobjc.m", + "GPBWrappers.pbobjc.m", + "GPBArray.m", + "GPBCodedInputStream.m", + "GPBCodedOutputStream.m", + "GPBDescriptor.m", + "GPBDictionary.m", + "GPBExtensionInternals.m", + "GPBExtensionRegistry.m", + "GPBMessage.m", + "GPBRootObject.m", + "GPBUnknownField.m", + "GPBUnknownFieldSet.m", + "GPBUtilities.m", + "GPBWellKnownTypes.m", + "GPBWireFormat.m", + ], + visibility = ["//visibility:public"], +) diff --git a/objectivec/DevTools/compile_testing_protos.sh b/objectivec/DevTools/compile_testing_protos.sh index 021e03d0ed..69c32f920b 100755 --- a/objectivec/DevTools/compile_testing_protos.sh +++ b/objectivec/DevTools/compile_testing_protos.sh @@ -95,7 +95,7 @@ cd "${SRCROOT}/.." # ----------------------------------------------------------------------------- RUN_PROTOC=no -# Check to if all the output files exist (incase a new one got added). +# Check to if all the output files exist (in case a new one got added). for PROTO_FILE in "${CORE_PROTO_FILES[@]}" "${OBJC_TEST_PROTO_FILES[@]}"; do DIR=${PROTO_FILE%/*} diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh index 84ed8e9914..4df131408e 100755 --- a/objectivec/DevTools/full_mac_build.sh +++ b/objectivec/DevTools/full_mac_build.sh @@ -285,7 +285,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit # 10.x also seems to often fail running destinations in parallel (with - # 32bit one include atleast) + # 32bit one include at least) -disable-concurrent-destination-testing ) ;; diff --git a/objectivec/DevTools/pddm.py b/objectivec/DevTools/pddm.py index dacf7bba00..b572cc75b6 100755 --- a/objectivec/DevTools/pddm.py +++ b/objectivec/DevTools/pddm.py @@ -645,7 +645,7 @@ def main(args): opts, extra_args = parser.parse_args(args) if not extra_args: - parser.error('Need atleast one file to process') + parser.error('Need at least one file to process') result = 0 for a_path in extra_args: diff --git a/objectivec/GPBExtensionInternals.m b/objectivec/GPBExtensionInternals.m index 290c82a1bb..bacec5740a 100644 --- a/objectivec/GPBExtensionInternals.m +++ b/objectivec/GPBExtensionInternals.m @@ -361,8 +361,8 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension, if (existingValue) { message = [existingValue retain]; } else { - GPBDescriptor *decriptor = [extension.msgClass descriptor]; - message = [[decriptor.messageClass alloc] init]; + GPBDescriptor *descriptor = [extension.msgClass descriptor]; + message = [[descriptor.messageClass alloc] init]; } if (description->dataType == GPBDataTypeGroup) { diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 8e6aaf16e9..7b1263fde9 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -3286,7 +3286,7 @@ static void ResolveIvarSet(__unsafe_unretained GPBFieldDescriptor *field, // if a sub message in a field has extensions, the issue still exists. A // recursive check could be done here (like the work in // GPBMessageDropUnknownFieldsRecursively()), but that has the potential to - // be expensive and could slow down serialization in DEBUG enought to cause + // be expensive and could slow down serialization in DEBUG enough to cause // developers other problems. NSLog(@"Warning: writing out a GPBMessage (%@) via NSCoding and it" @" has %ld extensions; when read back in, those fields will be" diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h index 92f0bac886..a328afc7c9 100644 --- a/objectivec/GPBTimestamp.pbobjc.h +++ b/objectivec/GPBTimestamp.pbobjc.h @@ -107,7 +107,16 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) { * .setNanos((int) ((millis % 1000) * 1000000)).build(); * * - * Example 5: Compute Timestamp from current time in Python. + * Example 5: Compute Timestamp from Java `Instant.now()`. + * + * Instant now = Instant.now(); + * + * Timestamp timestamp = + * Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + * .setNanos(now.getNano()).build(); + * + * + * Example 6: Compute Timestamp from current time in Python. * * timestamp = Timestamp() * timestamp.GetCurrentTime() diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m index ee79d00192..e13210210d 100644 --- a/objectivec/GPBUtilities.m +++ b/objectivec/GPBUtilities.m @@ -219,7 +219,7 @@ void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion) { // Library is too old for headers. [NSException raise:NSInternalInconsistencyException format:@"Linked to ProtocolBuffer runtime version %d," - @" but code compiled needing atleast %d!", + @" but code compiled needing at least %d!", GOOGLE_PROTOBUF_OBJC_VERSION, objcRuntimeVersion]; } if (objcRuntimeVersion < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION) { diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h index 9c29c39c0b..a620288267 100644 --- a/objectivec/GPBUtilities_PackagePrivate.h +++ b/objectivec/GPBUtilities_PackagePrivate.h @@ -304,7 +304,7 @@ void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel); // Helper for text format name encoding. -// decodeData is the data describing the sepecial decodes. +// decodeData is the data describing the special decodes. // key and inputString are the input that needs decoding. NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, NSString *inputString); diff --git a/objectivec/README.md b/objectivec/README.md index 5982939290..2583779d38 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -168,7 +168,7 @@ supported keys are: Any number of files can be listed for a framework, just separate them with commas. - There can be multiple lines listing the same frameworkName incase it has a + There can be multiple lines listing the same frameworkName in case it has a lot of proto files included in it; and having multiple lines makes things easier to read. diff --git a/objectivec/Tests/CocoaPods/run_tests.sh b/objectivec/Tests/CocoaPods/run_tests.sh index 6d3e12be30..35bcc18df7 100755 --- a/objectivec/Tests/CocoaPods/run_tests.sh +++ b/objectivec/Tests/CocoaPods/run_tests.sh @@ -90,7 +90,7 @@ cleanup() { echo "Cleaning up..." # Generally don't let things fail, and eat common stdout, but let stderr show - # incase something does hiccup. + # in case something does hiccup. xcodebuild -workspace "${TEST_NAME}.xcworkspace" -scheme "${TEST_NAME}" clean > /dev/null || true pod deintegrate > /dev/null || true # Flush the cache so nothing is left behind. diff --git a/objectivec/Tests/GPBCodedInputStreamTests.m b/objectivec/Tests/GPBCodedInputStreamTests.m index f5aa69038f..6cd5a1ffd7 100644 --- a/objectivec/Tests/GPBCodedInputStreamTests.m +++ b/objectivec/Tests/GPBCodedInputStreamTests.m @@ -422,7 +422,7 @@ - (void)testBOMWithinStrings { // We've seen servers that end up with BOMs within strings (not always at the // start, and sometimes in multiple places), make sure they always parse - // correctly. (Again, this is inpart incase a custom string class is ever + // correctly. (Again, this is inpart in case a custom string class is ever // used again.) const char* strs[] = { "\xEF\xBB\xBF String with BOM", diff --git a/objectivec/Tests/GPBCodedOuputStreamTests.m b/objectivec/Tests/GPBCodedOuputStreamTests.m index 6c9144fb57..a9934acdac 100644 --- a/objectivec/Tests/GPBCodedOuputStreamTests.m +++ b/objectivec/Tests/GPBCodedOuputStreamTests.m @@ -400,7 +400,7 @@ - (void)testWriteStringsWithZeroChar { // Unicode allows `\0` as a character, and NSString is a class cluster, so - // there are a few different classes that could end up beind a given string. + // there are a few different classes that could end up behind a given string. // Historically, we've seen differences based on constant strings in code and // strings built via the NSString apis. So this round trips them to ensure // they are acting as expected. diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 571d3e41cd..4615ed31aa 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -94,11 +94,12 @@ static void RepeatedField_destructor(zend_object* obj) { zend_object_std_dtor(&intern->std); } -static HashTable *RepeatedField_GetProperties(zval *object TSRMLS_DC) { +static HashTable *RepeatedField_GetProperties(PROTO_VAL *object) { return NULL; // We do not have a properties table. } -static zval *RepeatedField_GetPropertyPtrPtr(zval *object, zval *member, +static zval *RepeatedField_GetPropertyPtrPtr(PROTO_VAL *object, + PROTO_STR *member, int type, void **cache_slot) { return NULL; // We don't offer direct references to our properties. } @@ -392,6 +393,15 @@ PHP_METHOD(RepeatedField, getIterator) { RETURN_ZVAL(&ret, 0, 1); } +ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 1) + ZEND_ARG_INFO(0, newval) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() @@ -405,8 +415,8 @@ ZEND_BEGIN_ARG_INFO(arginfo_void, 0) ZEND_END_ARG_INFO() static zend_function_entry repeated_field_methods[] = { - PHP_ME(RepeatedField, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, append, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, append, arginfo_append, ZEND_ACC_PUBLIC) PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) diff --git a/php/ext/google/protobuf/convert.c b/php/ext/google/protobuf/convert.c index dd076c5f1a..1c2f6288b5 100644 --- a/php/ext/google/protobuf/convert.c +++ b/php/ext/google/protobuf/convert.c @@ -92,20 +92,55 @@ PHP_METHOD(Util, checkRepeatedField) { RETURN_ZVAL(val, 1, 0); } +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkPrimitive, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMessage, 0, 0, 2) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMapField, 0, 0, 3) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, key_type) + ZEND_ARG_INFO(0, value_type) + ZEND_ARG_INFO(0, value_class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkRepeatedField, 0, 0, 2) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + static zend_function_entry util_methods[] = { - PHP_ME(Util, checkInt32, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkUint32, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkInt64, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkUint64, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkEnum, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkFloat, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkDouble, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkBool, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkBytes, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkMapField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkRepeatedField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkInt32, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkUint32, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkInt64, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkUint64, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkEnum, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkFloat, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkDouble, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkBool, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkString, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkBytes, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkMessage, arginfo_checkMessage, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkMapField, arginfo_checkMapField, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkRepeatedField, arginfo_checkRepeatedField, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index c76134d86b..37dd50c182 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -180,8 +180,7 @@ PHP_METHOD(EnumDescriptor, getValue) { zend_long index; zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } @@ -284,8 +283,7 @@ PHP_METHOD(OneofDescriptor, getField) { zend_long index; zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } @@ -615,8 +613,7 @@ PHP_METHOD(Descriptor, getField) { zval ret; zend_long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } @@ -658,8 +655,7 @@ PHP_METHOD(Descriptor, getOneofDecl) { zend_long index; zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } @@ -799,8 +795,8 @@ PHP_METHOD(DescriptorPool, getDescriptorByClassName) { zend_string *str; zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, - &classname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == + FAILURE) { return; } @@ -828,8 +824,8 @@ PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) { zend_string *str; zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, - &classname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == + FAILURE) { return; } @@ -856,8 +852,8 @@ PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { zend_long protoname_len; const upb_msgdef *m; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protoname, - &protoname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protoname, &protoname_len) == + FAILURE) { return; } diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index 0217c6491e..f29c18c9bd 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -90,12 +90,12 @@ static void MapField_destructor(zend_object* obj) { zend_object_std_dtor(&intern->std); } -static zval *Map_GetPropertyPtrPtr(zval *object, zval *member, int type, - void **cache_slot) { +static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member, + int type, void **cache_slot) { return NULL; // We don't offer direct references to our properties. } -static HashTable *map_get_properties(zval *object TSRMLS_DC) { +static HashTable *Map_GetProperties(PROTO_VAL *object) { return NULL; // We do not have a properties table. } @@ -378,6 +378,12 @@ PHP_METHOD(MapField, getIterator) { RETURN_ZVAL(&ret, 0, 1); } +ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2) + ZEND_ARG_INFO(0, key_type) + ZEND_ARG_INFO(0, value_type) + ZEND_ARG_INFO(0, value_class) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() @@ -391,7 +397,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_void, 0) ZEND_END_ARG_INFO() static zend_function_entry MapField_methods[] = { - PHP_ME(MapField, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(MapField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) @@ -572,7 +578,7 @@ void Map_ModuleInit() { h = &MapField_object_handlers; memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); h->dtor_obj = MapField_destructor; - h->get_properties = map_get_properties; + h->get_properties = Map_GetProperties; h->get_property_ptr_ptr = Map_GetPropertyPtrPtr; INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapFieldIter", diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 20dd37a76e..63d2b084aa 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -95,10 +95,10 @@ static void Message_dtor(zend_object* obj) { * * Helper function to look up a field given a member name (as a string). */ -static const upb_fielddef *get_field(Message *msg, zval *member) { +static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) { const upb_msgdef *m = msg->desc->msgdef; const upb_fielddef *f = - upb_msgdef_ntof(m, Z_STRVAL_P(member), Z_STRLEN_P(member)); + upb_msgdef_ntof(m, PROTO_STRVAL_P(member), PROTO_STRLEN_P(member)); if (!f) { zend_throw_exception_ex(NULL, 0, "No such property %s.", @@ -108,6 +108,78 @@ static const upb_fielddef *get_field(Message *msg, zval *member) { return f; } +/** + * Message_has_property() + * + * Object handler for testing whether a property exists. Called when PHP code + * does any of: + * + * isset($message->foobar); + * property_exists($message->foobar); + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like this + * (if the field has presence): + * + * public function hasOptionalInt32() + * { + * return isset($this->optional_int32); + * } + */ +static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member, + int has_set_exists, + void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (!f) return 0; + + if (!upb_fielddef_haspresence(f)) { + zend_throw_exception_ex( + NULL, 0, + "Cannot call isset() on field %s which does not have presence.", + ZSTR_VAL(intern->desc->class_entry->name)); + return 0; + } + + return upb_msg_has(intern->msg, f); +} + +/** + * Message_unset_property() + * + * Object handler for unsetting a property. Called when PHP code calls: + * does any of: + * + * unset($message->foobar); + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like this + * (if the field has presence): + * + * public function clearOptionalInt32() + * { + * unset($this->optional_int32); + * } + */ +static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member, + void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (!f) return; + + if (!upb_fielddef_haspresence(f)) { + zend_throw_exception_ex( + NULL, 0, + "Cannot call unset() on field %s which does not have presence.", + ZSTR_VAL(intern->desc->class_entry->name)); + return; + } + + upb_msg_clearfield(intern->msg, f); +} + /** * Message_read_property() * @@ -126,9 +198,9 @@ static const upb_fielddef *get_field(Message *msg, zval *member) { * We lookup the field and return the scalar, RepeatedField, or MapField for * this field. */ -static zval *Message_read_property(zval *obj, zval *member, int type, - void **cache_slot, zval *rv) { - Message* intern = (Message*)Z_OBJ_P(obj); +static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member, + int type, void **cache_slot, zval *rv) { + Message* intern = PROTO_MSG_P(obj); const upb_fielddef *f = get_field(intern, member); upb_arena *arena = Arena_Get(&intern->arena); @@ -170,29 +242,41 @@ static zval *Message_read_property(zval *obj, zval *member, int type, * The C extension version of checkInt32() doesn't actually check anything, so * we perform all checking and conversion in this function. */ -static void Message_write_property(zval *obj, zval *member, zval *val, - void **cache_slot) { - Message* intern = (Message*)Z_OBJ_P(obj); +static PROTO_RETURN_VAL Message_write_property( + PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); const upb_fielddef *f = get_field(intern, member); upb_arena *arena = Arena_Get(&intern->arena); upb_msgval msgval; - if (!f) return; + if (!f) goto error; if (upb_fielddef_ismap(f)) { msgval.map_val = MapField_GetUpbMap(val, f, arena); - if (!msgval.map_val) return; + if (!msgval.map_val) goto error; } else if (upb_fielddef_isseq(f)) { msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); - if (!msgval.array_val) return; + if (!msgval.array_val) goto error; } else { upb_fieldtype_t type = upb_fielddef_type(f); const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena); - if (!ok) return; + if (!ok) goto error; } upb_msg_set(intern->msg, f, msgval, arena); +#if PHP_VERSION_ID < 704000 + return; +#else + return val; +#endif + +error: +#if PHP_VERSION_ID < 704000 + return; +#else + return &EG(error_zval); +#endif } /** @@ -202,7 +286,8 @@ static void Message_write_property(zval *obj, zval *member, zval *val, * reference to our internal properties. We don't support this, so we return * NULL. */ -static zval *Message_get_property_ptr_ptr(zval *object, zval *member, int type, +static zval *Message_get_property_ptr_ptr(PROTO_VAL *object, PROTO_STR *member, + int type, void **cache_slot) { return NULL; // We do not have a properties table. } @@ -213,7 +298,7 @@ static zval *Message_get_property_ptr_ptr(zval *object, zval *member, int type, * Object handler for the get_properties event in PHP. This returns a HashTable * of our internal properties. We don't support this, so we return NULL. */ -static HashTable* Message_get_properties(zval* object TSRMLS_DC) { +static HashTable *Message_get_properties(PROTO_VAL *object) { return NULL; // We don't offer direct references to our properties. } @@ -549,7 +634,7 @@ PHP_METHOD(Message, serializeToJsonString) { zend_bool preserve_proto_fieldnames = false; upb_status status; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &preserve_proto_fieldnames) == FAILURE) { return; } @@ -800,20 +885,36 @@ PHP_METHOD(Message, writeOneof) { upb_msg_set(intern->msg, f, msgval, arena); } +ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mergeFrom, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_read, 0, 0, 1) + ZEND_ARG_INFO(0, field) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_write, 0, 0, 2) + ZEND_ARG_INFO(0, field) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + static zend_function_entry Message_methods[] = { - PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, discardUnknownFields, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, serializeToJsonString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFromJsonString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFrom, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, readWrapperValue, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, writeWrapperValue, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, readOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, writeOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, whichOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, __construct, NULL, ZEND_ACC_PROTECTED) + PHP_ME(Message, clear, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, discardUnknownFields, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, serializeToString, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFromString, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, serializeToJsonString, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFromJsonString, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFrom, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, readWrapperValue, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, writeWrapperValue, arginfo_write, ZEND_ACC_PROTECTED) + PHP_ME(Message, readOneof, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, writeOneof, arginfo_write, ZEND_ACC_PROTECTED) + PHP_ME(Message, whichOneof, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, __construct, arginfo_void, ZEND_ACC_PROTECTED) ZEND_FE_END }; @@ -836,6 +937,8 @@ void Message_ModuleInit() { h->dtor_obj = Message_dtor; h->read_property = Message_read_property; h->write_property = Message_write_property; + h->has_property = Message_has_property; + h->unset_property = Message_unset_property; h->get_properties = Message_get_properties; h->get_property_ptr_ptr = Message_get_property_ptr_ptr; } diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index b8ae8bae71..037fa90d93 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,11 +10,11 @@ protobuf-opensource@google.com yes - 2020-06-01 - + 2020-08-14 + - 3.12.3 - 3.12.3 + 3.13.0 + 3.13.0 stable @@ -51,7 +51,7 @@ - 5.5.9 + 7.0.0 1.4.0 @@ -619,5 +619,61 @@ G A release. 3-Clause BSD License GA release. + + + 3.13.0RC1 + 3.13.0 + + + beta + beta + + 2020-08-05 + + 3-Clause BSD License + GA release. + + + + 3.13.0RC2 + 3.13.0 + + + beta + beta + + 2020-08-05 + + 3-Clause BSD License + GA release. + + + + 3.13.0RC3 + 3.13.0 + + + beta + beta + + 2020-08-12 + + 3-Clause BSD License + GA release. + + + + 3.13.0 + 3.13.0 + + + stable + stable + + 2020-08-14 + + 3-Clause BSD License + GA release. + diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index f5ea2ef20a..6ce85f1e6a 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -174,6 +174,11 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #else #define UPB_INFINITY (1.0 / 0.0) #endif +#ifdef NAN +#define UPB_NAN NAN +#else +#define UPB_NAN (0.0 / 0.0) +#endif #include #include @@ -235,11 +240,13 @@ static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | (1 << UPB_DTYPE_SFIXED64); /* Op: an action to be performed for a wire-type/field-type combination. */ -#define OP_SCALAR_LG2(n) (n) -#define OP_FIXPCK_LG2(n) (n + 4) -#define OP_VARPCK_LG2(n) (n + 8) +#define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */ #define OP_STRING 4 -#define OP_SUBMSG 5 +#define OP_BYTES 5 +#define OP_SUBMSG 6 +/* Ops above are scalar-only. Repeated fields can use any op. */ +#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ +#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ static const int8_t varint_ops[19] = { -1, /* field not found */ @@ -277,7 +284,7 @@ static const int8_t delim_ops[37] = { OP_STRING, /* STRING */ -1, /* GROUP */ OP_SUBMSG, /* MESSAGE */ - OP_STRING, /* BYTES */ + OP_BYTES, /* BYTES */ -1, /* UINT32 */ -1, /* ENUM */ -1, /* SFIXED32 */ @@ -296,7 +303,7 @@ static const int8_t delim_ops[37] = { OP_STRING, /* REPEATED STRING */ OP_SUBMSG, /* REPEATED GROUP */ OP_SUBMSG, /* REPEATED MESSAGE */ - OP_STRING, /* REPEATED BYTES */ + OP_BYTES, /* REPEATED BYTES */ OP_VARPCK_LG2(2), /* REPEATED UINT32 */ OP_VARPCK_LG2(2), /* REPEATED ENUM */ OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */ @@ -328,6 +335,40 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); } +void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { + static const uint8_t utf8_offset[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + int i, j; + uint8_t offset; + + i = 0; + while (i < len) { + offset = utf8_offset[(uint8_t)buf[i]]; + if (offset == 0 || i + offset > len) { + decode_err(d); + } + for (j = i + 1; j < i + offset; j++) { + if ((buf[j] & 0xc0) != 0x80) { + decode_err(d); + } + } + i += offset; + } + if (i != len) decode_err(d); +} + static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { bool need_realloc = arr->size - arr->len < elem; if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) { @@ -395,7 +436,7 @@ static void decode_munge(int type, wireval *val) { static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, uint32_t field_number) { - static upb_msglayout_field none = {0}; + static upb_msglayout_field none = {0, 0, 0, 0, 0, 0}; /* Lots of optimization opportunities here. */ int i; @@ -473,7 +514,10 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, memcpy(mem, &val, 1 << op); return ptr; case OP_STRING: - /* Append string. */ + decode_verifyutf8(d, val.str_val.data, val.str_val.size); + /* Fallthrough. */ + case OP_BYTES: + /* Append bytes. */ mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void); arr->len++; @@ -607,6 +651,9 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, break; } case OP_STRING: + decode_verifyutf8(d, val.str_val.data, val.str_val.size); + /* Fallthrough. */ + case OP_BYTES: memcpy(mem, &val, sizeof(upb_strview)); break; case OP_SCALAR_LG2(3): @@ -1892,17 +1939,6 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { return success; } -bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) { - return upb_inttable_insert2(t, upb_inttable_count(t), val, a); -} - -upb_value upb_inttable_pop(upb_inttable *t) { - upb_value val; - bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val); - UPB_ASSERT(ok); - return val; -} - bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, upb_alloc *a) { return upb_inttable_insert2(t, (uintptr_t)key, val, a); @@ -2328,15 +2364,28 @@ struct upb_arena { static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16); +static upb_arena *arena_findroot(upb_arena *a) { + /* Path splitting keeps time complexity down, see: + * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */ + while (a->parent != a) { + upb_arena *next = a->parent; + a->parent = next->parent; + a = next; + } + return a; +} + static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) { mem_block *block = ptr; + upb_arena *root = arena_findroot(a); - block->next = a->freelist; + /* The block is for arena |a|, but should appear in the freelist of |root|. */ + block->next = root->freelist; block->size = (uint32_t)size; block->cleanups = 0; - a->freelist = block; + root->freelist = block; a->last_size = block->size; - if (!a->freelist_tail) a->freelist_tail = block; + if (!root->freelist_tail) root->freelist_tail = block; a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char); a->head.end = UPB_PTR_AT(block, size, char); @@ -2371,17 +2420,6 @@ static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, return upb_arena_realloc(a, ptr, oldsize, size); } -static upb_arena *arena_findroot(upb_arena *a) { - /* Path splitting keeps time complexity down, see: - * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */ - while (a->parent != a) { - upb_arena *next = a->parent; - a->parent = next->parent; - a = next; - } - return a; -} - /* Public Arena API ***********************************************************/ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { @@ -2540,9 +2578,9 @@ static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] }; static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = { - {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, - {2, UPB_SIZE(12, 24), 2, 0, 9, 1}, - {3, UPB_SIZE(36, 72), 0, 0, 9, 3}, + {1, UPB_SIZE(4, 8), 1, 0, 12, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 12, 1}, + {3, UPB_SIZE(36, 72), 0, 0, 12, 3}, {4, UPB_SIZE(40, 80), 0, 0, 11, 3}, {5, UPB_SIZE(44, 88), 0, 1, 11, 3}, {6, UPB_SIZE(48, 96), 0, 4, 11, 3}, @@ -2551,7 +2589,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] {9, UPB_SIZE(32, 64), 5, 5, 11, 1}, {10, UPB_SIZE(56, 112), 0, 0, 5, 3}, {11, UPB_SIZE(60, 120), 0, 0, 5, 3}, - {12, UPB_SIZE(20, 40), 3, 0, 9, 1}, + {12, UPB_SIZE(20, 40), 3, 0, 12, 1}, }; const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { @@ -2571,7 +2609,7 @@ static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = { }; static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { - {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {1, UPB_SIZE(4, 8), 1, 0, 12, 1}, {2, UPB_SIZE(16, 32), 0, 4, 11, 3}, {3, UPB_SIZE(20, 40), 0, 0, 11, 3}, {4, UPB_SIZE(24, 48), 0, 3, 11, 3}, @@ -2580,7 +2618,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { {7, UPB_SIZE(12, 24), 2, 5, 11, 1}, {8, UPB_SIZE(36, 72), 0, 6, 11, 3}, {9, UPB_SIZE(40, 80), 0, 2, 11, 3}, - {10, UPB_SIZE(44, 88), 0, 0, 9, 3}, + {10, UPB_SIZE(44, 88), 0, 0, 12, 3}, }; const upb_msglayout google_protobuf_DescriptorProto_msginit = { @@ -2635,16 +2673,16 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1 }; static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = { - {1, UPB_SIZE(36, 40), 6, 0, 9, 1}, - {2, UPB_SIZE(44, 56), 7, 0, 9, 1}, + {1, UPB_SIZE(36, 40), 6, 0, 12, 1}, + {2, UPB_SIZE(44, 56), 7, 0, 12, 1}, {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, - {6, UPB_SIZE(52, 72), 8, 0, 9, 1}, - {7, UPB_SIZE(60, 88), 9, 0, 9, 1}, + {6, UPB_SIZE(52, 72), 8, 0, 12, 1}, + {7, UPB_SIZE(60, 88), 9, 0, 12, 1}, {8, UPB_SIZE(76, 120), 11, 0, 11, 1}, {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, - {10, UPB_SIZE(68, 104), 10, 0, 9, 1}, + {10, UPB_SIZE(68, 104), 10, 0, 12, 1}, {17, UPB_SIZE(32, 32), 5, 0, 8, 1}, }; @@ -2659,7 +2697,7 @@ static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1 }; static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = { - {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {1, UPB_SIZE(4, 8), 1, 0, 12, 1}, {2, UPB_SIZE(12, 24), 2, 0, 11, 1}, }; @@ -2676,11 +2714,11 @@ static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] }; static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = { - {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {1, UPB_SIZE(4, 8), 1, 0, 12, 1}, {2, UPB_SIZE(16, 32), 0, 2, 11, 3}, {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, {4, UPB_SIZE(20, 40), 0, 0, 11, 3}, - {5, UPB_SIZE(24, 48), 0, 0, 9, 3}, + {5, UPB_SIZE(24, 48), 0, 0, 12, 3}, }; const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { @@ -2705,7 +2743,7 @@ static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_subms }; static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = { - {1, UPB_SIZE(8, 8), 2, 0, 9, 1}, + {1, UPB_SIZE(8, 8), 2, 0, 12, 1}, {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, {3, UPB_SIZE(16, 24), 3, 0, 11, 1}, }; @@ -2722,7 +2760,7 @@ static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs }; static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = { - {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {1, UPB_SIZE(4, 8), 1, 0, 12, 1}, {2, UPB_SIZE(16, 32), 0, 0, 11, 3}, {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, }; @@ -2738,9 +2776,9 @@ static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[ }; static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = { - {1, UPB_SIZE(4, 8), 3, 0, 9, 1}, - {2, UPB_SIZE(12, 24), 4, 0, 9, 1}, - {3, UPB_SIZE(20, 40), 5, 0, 9, 1}, + {1, UPB_SIZE(4, 8), 3, 0, 12, 1}, + {2, UPB_SIZE(12, 24), 4, 0, 12, 1}, + {3, UPB_SIZE(20, 40), 5, 0, 12, 1}, {4, UPB_SIZE(28, 56), 6, 0, 11, 1}, {5, UPB_SIZE(1, 1), 1, 0, 8, 1}, {6, UPB_SIZE(2, 2), 2, 0, 8, 1}, @@ -2757,11 +2795,11 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { }; static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { - {1, UPB_SIZE(28, 32), 11, 0, 9, 1}, - {8, UPB_SIZE(36, 48), 12, 0, 9, 1}, + {1, UPB_SIZE(28, 32), 11, 0, 12, 1}, + {8, UPB_SIZE(36, 48), 12, 0, 12, 1}, {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, - {11, UPB_SIZE(44, 64), 13, 0, 9, 1}, + {11, UPB_SIZE(44, 64), 13, 0, 12, 1}, {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, @@ -2769,14 +2807,14 @@ static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, - {36, UPB_SIZE(52, 80), 14, 0, 9, 1}, - {37, UPB_SIZE(60, 96), 15, 0, 9, 1}, - {39, UPB_SIZE(68, 112), 16, 0, 9, 1}, - {40, UPB_SIZE(76, 128), 17, 0, 9, 1}, - {41, UPB_SIZE(84, 144), 18, 0, 9, 1}, + {36, UPB_SIZE(52, 80), 14, 0, 12, 1}, + {37, UPB_SIZE(60, 96), 15, 0, 12, 1}, + {39, UPB_SIZE(68, 112), 16, 0, 12, 1}, + {40, UPB_SIZE(76, 128), 17, 0, 12, 1}, + {41, UPB_SIZE(84, 144), 18, 0, 12, 1}, {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, - {44, UPB_SIZE(92, 160), 19, 0, 9, 1}, - {45, UPB_SIZE(100, 176), 20, 0, 9, 1}, + {44, UPB_SIZE(92, 160), 19, 0, 12, 1}, + {45, UPB_SIZE(100, 176), 20, 0, 12, 1}, {999, UPB_SIZE(108, 192), 0, 0, 11, 3}, }; @@ -2906,12 +2944,12 @@ static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = { {2, UPB_SIZE(56, 80), 0, 0, 11, 3}, - {3, UPB_SIZE(32, 32), 4, 0, 9, 1}, + {3, UPB_SIZE(32, 32), 4, 0, 12, 1}, {4, UPB_SIZE(8, 8), 1, 0, 4, 1}, {5, UPB_SIZE(16, 16), 2, 0, 3, 1}, {6, UPB_SIZE(24, 24), 3, 0, 1, 1}, {7, UPB_SIZE(40, 48), 5, 0, 12, 1}, - {8, UPB_SIZE(48, 64), 6, 0, 9, 1}, + {8, UPB_SIZE(48, 64), 6, 0, 12, 1}, }; const upb_msglayout google_protobuf_UninterpretedOption_msginit = { @@ -2921,7 +2959,7 @@ const upb_msglayout google_protobuf_UninterpretedOption_msginit = { }; static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { - {1, UPB_SIZE(4, 8), 2, 0, 9, 2}, + {1, UPB_SIZE(4, 8), 2, 0, 12, 2}, {2, UPB_SIZE(1, 1), 1, 0, 8, 2}, }; @@ -2948,9 +2986,9 @@ const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED}, {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED}, - {3, UPB_SIZE(4, 8), 1, 0, 9, 1}, - {4, UPB_SIZE(12, 24), 2, 0, 9, 1}, - {6, UPB_SIZE(28, 56), 0, 0, 9, 3}, + {3, UPB_SIZE(4, 8), 1, 0, 12, 1}, + {4, UPB_SIZE(12, 24), 2, 0, 12, 1}, + {6, UPB_SIZE(28, 56), 0, 0, 12, 3}, }; const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { @@ -2975,7 +3013,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED}, - {2, UPB_SIZE(12, 16), 3, 0, 9, 1}, + {2, UPB_SIZE(12, 16), 3, 0, 12, 1}, {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, }; @@ -4383,6 +4421,13 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { field->descriptortype = upb_fielddef_descriptortype(f); field->label = upb_fielddef_label(f); + if (field->descriptortype == UPB_DTYPE_STRING && + f->file->syntax == UPB_SYNTAX_PROTO2) { + /* See TableDescriptorType() in upbc/generator.cc for details and + * rationale. */ + field->descriptortype = UPB_DTYPE_BYTES; + } + if (upb_fielddef_ismap(f)) { field->label = _UPB_LABEL_MAP; } else if (upb_fielddef_packed(f)) { @@ -4918,13 +4963,21 @@ static bool create_fielddef( f->oneof = NULL; } - if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) { - options = google_protobuf_FieldDescriptorProto_options(field_proto); - f->lazy_ = google_protobuf_FieldOptions_lazy(options); + options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ? + google_protobuf_FieldDescriptorProto_options(field_proto) : NULL; + + if (options && google_protobuf_FieldOptions_has_packed(options)) { f->packed_ = google_protobuf_FieldOptions_packed(options); + } else { + /* Repeated fields default to packed for proto3 only. */ + f->packed_ = upb_fielddef_isprimitive(f) && + f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3; + } + + if (options) { + f->lazy_ = google_protobuf_FieldOptions_lazy(options); } else { f->lazy_ = false; - f->packed_ = false; } return true; @@ -5188,7 +5241,7 @@ static bool build_filedef( const google_protobuf_FieldDescriptorProto *const *exts; const upb_strview* strs; size_t i, n; - decl_counts counts = {0}; + decl_counts counts = {0, 0, 0}; count_types_in_file(file_proto, &counts); @@ -5612,7 +5665,11 @@ const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, if (upb_oneof_done(&i)) return false; f = upb_oneof_iter_field(&i); field = upb_fielddef_layout(f); - oneof_case = _upb_getoneofcase_field(msg, field); + if (in_oneof(field)) { + oneof_case = _upb_getoneofcase_field(msg, field); + } else { + return _upb_hasbit_field(msg, field) ? f : NULL; + } return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL; } @@ -6341,6 +6398,7 @@ static upb_strview jsondec_string(jsondec *d) { upb_strview ret; ret.data = buf; ret.size = end - buf; + *end = '\0'; /* Needed for possible strtod(). */ return ret; } case '\\': @@ -6665,7 +6723,7 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { case JD_STRING: str = jsondec_string(d); if (jsondec_streql(str, "NaN")) { - val.double_val = 0.0 / 0.0; + val.double_val = UPB_NAN; } else if (jsondec_streql(str, "Infinity")) { val.double_val = UPB_INFINITY; } else if (jsondec_streql(str, "-Infinity")) { @@ -6822,7 +6880,7 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) { return; } - if (upb_fielddef_containingoneof(f) && + if (upb_fielddef_realcontainingoneof(f) && upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) { jsondec_err(d, "More than one field for this oneof."); } @@ -7655,7 +7713,7 @@ static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) { ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr); if (!ret) { - jsonenc_errf(e, "Couldn't find Any type: %.*s (full URL: " UPB_STRVIEW_FORMAT ")", (int)(end - ptr), ptr, UPB_STRVIEW_ARGS(type_url)); + jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr); } return ret; @@ -8071,6 +8129,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE #undef UPB_INFINITY +#undef UPB_NAN #undef UPB_MSVC_VSNPRINTF #undef _upb_snprintf #undef _upb_vsnprintf diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index a07885ff9c..666ec76d05 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -173,6 +173,11 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #else #define UPB_INFINITY (1.0 / 0.0) #endif +#ifdef NAN +#define UPB_NAN NAN +#else +#define UPB_NAN (0.0 / 0.0) +#endif /* ** upb_decode: parsing into a upb_msg using a upb_msglayout. */ @@ -208,7 +213,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); ** store pointers or integers of at least 32 bits (upb isn't really useful on ** systems where sizeof(void*) < 4). ** -** The table must be homogenous (all values of the same type). In debug +** The table must be homogeneous (all values of the same type). In debug ** mode, we check this on insert and lookup. */ @@ -799,15 +804,6 @@ UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key, * invalidate iterators. */ bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val); -/* Handy routines for treating an inttable like a stack. May not be mixed with - * other insert/remove calls. */ -bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a); -upb_value upb_inttable_pop(upb_inttable *t); - -UPB_INLINE bool upb_inttable_push(upb_inttable *t, upb_value val) { - return upb_inttable_push2(t, val, &upb_alloc_global); -} - /* Convenience routines for inttables with pointer keys. */ bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, upb_alloc *a); @@ -1072,7 +1068,7 @@ UPB_INLINE uint32_t _upb_getoneofcase(const void *msg, size_t case_ofs) { UPB_INLINE size_t _upb_oneofcase_ofs(const upb_msglayout_field *f) { UPB_ASSERT(f->presence < 0); - return ~(int64_t)f->presence; + return ~(ptrdiff_t)f->presence; } UPB_INLINE uint32_t *_upb_oneofcase_field(upb_msg *msg, @@ -3831,7 +3827,7 @@ extern "C" { #endif enum { - /* When set, emits 0/default values. TOOD(haberman): proto3 only? */ + /* When set, emits 0/default values. TODO(haberman): proto3 only? */ UPB_JSONENC_EMITDEFAULTS = 1, /* When set, use normal (snake_caes) field names instead of JSON (camelCase) @@ -3879,6 +3875,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE #undef UPB_INFINITY +#undef UPB_NAN #undef UPB_MSVC_VSNPRINTF #undef _upb_snprintf #undef _upb_vsnprintf diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index 15c8f9bd72..fa1cc114b1 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -273,11 +273,18 @@ const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) { zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name); if (!ret && ce->create_object) { +#if PHP_VERSION_ID < 80000 zval tmp; zval zv; ZVAL_OBJ(&tmp, ce->create_object(ce)); zend_call_method_with_0_params(&tmp, ce, NULL, "__construct", &zv); zval_ptr_dtor(&tmp); +#else + zval zv; + zend_object *tmp = ce->create_object(ce); + zend_call_method_with_0_params(tmp, ce, NULL, "__construct", &zv); + OBJ_RELEASE(tmp); +#endif zval_ptr_dtor(&zv); ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name); } diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 6a7afae061..3188fe7dcb 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -43,6 +43,34 @@ const zval *get_generated_pool(); #define GC_DELREF(h) --GC_REFCOUNT(h) #endif +// Since php 7.4, the write_property() object handler now returns the assigned +// value (after possible type coercions) rather than void. +// https://github.com/php/php-src/blob/PHP-7.4.0/UPGRADING.INTERNALS#L171-L173 +#if PHP_VERSION_ID < 70400 +#define PROTO_RETURN_VAL void +#else +#define PROTO_RETURN_VAL zval* +#endif + +// Sine php 8.0, the Object Handlers API was changed to receive zend_object* +// instead of zval* and zend_string* instead of zval* for property names. +// https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39 +#if PHP_VERSION_ID < 80000 +#define PROTO_VAL zval +#define PROTO_STR zval +#define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj) +#define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj) +#define PROTO_STRLEN_P(obj) Z_STRLEN_P(obj) +#else +#define PROTO_VAL zend_object +#define PROTO_STR zend_string +#define PROTO_MSG_P(obj) (Message*)(obj) +#define PROTO_STRVAL_P(obj) ZSTR_VAL(obj) +#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj) +#endif + +#define PHP_PROTOBUF_VERSION "3.13.0" + // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: // * upb_msg* -> Message diff --git a/php/phpunit.xml b/php/phpunit.xml index 769037cf9a..8e7583596b 100644 --- a/php/phpunit.xml +++ b/php/phpunit.xml @@ -3,16 +3,16 @@ colors="true"> - tests/php_implementation_test.php - tests/array_test.php - tests/encode_decode_test.php - tests/generated_class_test.php - tests/generated_phpdoc_test.php - tests/map_field_test.php - tests/well_known_test.php - tests/descriptors_test.php - tests/generated_service_test.php - tests/wrapper_type_setters_test.php + tests/PhpImplementationTest.php + tests/ArrayTest.php + tests/EncodeDecodeTest.php + tests/GeneratedClassTest.php + tests/GeneratedPhpdocTest.php + tests/MapFieldTest.php + tests/WellKnownTest.php + tests/DescriptorsTest.php + tests/GeneratedServiceTest.php + tests/WrapperTypeSettersTest.php diff --git a/php/src/GPBMetadata/Google/Protobuf/Struct.php b/php/src/GPBMetadata/Google/Protobuf/Struct.php index 96b42af41d..8e6191dc7a 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Struct.php +++ b/php/src/GPBMetadata/Google/Protobuf/Struct.php @@ -15,29 +15,8 @@ class Struct return; } $pool->internalAddGeneratedFile(hex2bin( - "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e7072" . - "6f746f120f676f6f676c652e70726f746f6275662284010a065374727563" . - "7412330a066669656c647318012003280b32232e676f6f676c652e70726f" . - "746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669" . - "656c6473456e747279120b0a036b657918012001280912250a0576616c75" . - "6518022001280b32162e676f6f676c652e70726f746f6275662e56616c75" . - "653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518" . - "012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c5661" . - "6c7565480012160a0c6e756d6265725f76616c7565180220012801480012" . - "160a0c737472696e675f76616c7565180320012809480012140a0a626f6f" . - "6c5f76616c75651804200128084800122f0a0c7374727563745f76616c75" . - "6518052001280b32172e676f6f676c652e70726f746f6275662e53747275" . - "6374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f" . - "676c652e70726f746f6275662e4c69737456616c7565480042060a046b69" . - "6e6422330a094c69737456616c756512260a0676616c7565731801200328" . - "0b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e" . - "756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a1363" . - "6f6d2e676f6f676c652e70726f746f627566420b53747275637450726f74" . - "6f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275" . - "662f7074797065732f7374727563743b7374727563747062f80101a20203" . - "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" . - "6e5479706573620670726f746f33" - )); + "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e70726f746f120f676f6f676c652e70726f746f6275662284010a0653747275637412330a066669656c647318012003280b32232e676f6f676c652e70726f746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669656c6473456e747279120b0a036b657918012001280912250a0576616c756518022001280b32162e676f6f676c652e70726f746f6275662e56616c75653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c56616c7565480012160a0c6e756d6265725f76616c7565180220012801480012160a0c737472696e675f76616c7565180320012809480012140a0a626f6f6c5f76616c75651804200128084800122f0a0c7374727563745f76616c756518052001280b32172e676f6f676c652e70726f746f6275662e537472756374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f676c652e70726f746f6275662e4c69737456616c7565480042060a046b696e6422330a094c69737456616c756512260a0676616c75657318012003280b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a13636f6d2e676f6f676c652e70726f746f627566420b53747275637450726f746f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065732f7374727563743b7374727563747062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33" + ), true); static::$is_initialized = true; } diff --git a/php/src/Google/Protobuf/Descriptor.php b/php/src/Google/Protobuf/Descriptor.php index 986b81e12d..36436e2b70 100644 --- a/php/src/Google/Protobuf/Descriptor.php +++ b/php/src/Google/Protobuf/Descriptor.php @@ -97,4 +97,12 @@ class Descriptor { return count($this->internal_desc->getOneofDecl()); } + + /** + * @return int Number of real oneofs in message + */ + public function getRealOneofDeclCount() + { + return $this->internal_desc->getRealOneofDeclCount(); + } } diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php index ac9271f98b..6d08cea9da 100644 --- a/php/src/Google/Protobuf/FieldDescriptor.php +++ b/php/src/Google/Protobuf/FieldDescriptor.php @@ -114,4 +114,12 @@ class FieldDescriptor { return $this->internal_desc->isMap(); } + + /** + * @return boolean + */ + public function hasOptionalKeyword() + { + return $this->internal_desc->hasOptionalKeyword(); + } } diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php index 7cc689d028..e0822d779b 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php @@ -20,48 +20,39 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; */ private $field; - private $has_field = false; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; */ private $extension; - private $has_extension = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; */ private $nested_type; - private $has_nested_type = false; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; */ private $enum_type; - private $has_enum_type = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; */ private $extension_range; - private $has_extension_range = false; /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; */ private $oneof_decl; - private $has_oneof_decl = false; /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; */ protected $options = null; - private $has_options = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; */ private $reserved_range; - private $has_reserved_range = false; /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. @@ -69,7 +60,6 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated string reserved_name = 10; */ private $reserved_name; - private $has_reserved_name = false; /** * Constructor. @@ -102,7 +92,17 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -114,16 +114,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -142,16 +136,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->field = $arr; - $this->has_field = true; return $this; } - public function hasField() - { - return $this->has_field; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -170,16 +158,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; - $this->has_extension = true; return $this; } - public function hasExtension() - { - return $this->has_extension; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; * @return \Google\Protobuf\Internal\RepeatedField @@ -198,16 +180,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->nested_type = $arr; - $this->has_nested_type = true; return $this; } - public function hasNestedType() - { - return $this->has_nested_type; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; * @return \Google\Protobuf\Internal\RepeatedField @@ -226,16 +202,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; - $this->has_enum_type = true; return $this; } - public function hasEnumType() - { - return $this->has_enum_type; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; * @return \Google\Protobuf\Internal\RepeatedField @@ -254,16 +224,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class); $this->extension_range = $arr; - $this->has_extension_range = true; return $this; } - public function hasExtensionRange() - { - return $this->has_extension_range; - } - /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; * @return \Google\Protobuf\Internal\RepeatedField @@ -282,23 +246,27 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class); $this->oneof_decl = $arr; - $this->has_oneof_decl = true; return $this; } - public function hasOneofDecl() - { - return $this->has_oneof_decl; - } - /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; * @return \Google\Protobuf\Internal\MessageOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -310,16 +278,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MessageOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; * @return \Google\Protobuf\Internal\RepeatedField @@ -338,16 +300,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class); $this->reserved_range = $arr; - $this->has_reserved_range = true; return $this; } - public function hasReservedRange() - { - return $this->has_reserved_range; - } - /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. @@ -372,15 +328,9 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; - $this->has_reserved_name = true; return $this; } - public function hasReservedName() - { - return $this->has_reserved_name; - } - } diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php index 82b5695efe..1594913996 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php @@ -20,20 +20,17 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -61,7 +58,17 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -75,16 +82,10 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Exclusive. * @@ -93,7 +94,17 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -107,23 +118,27 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; * @return \Google\Protobuf\Internal\ExtensionRangeOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -135,16 +150,10 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php index 8022151abf..f099cc345a 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php @@ -24,15 +24,13 @@ class ReservedRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -59,7 +57,17 @@ class ReservedRange extends \Google\Protobuf\Internal\Message */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -73,16 +81,10 @@ class ReservedRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Exclusive. * @@ -91,7 +93,17 @@ class ReservedRange extends \Google\Protobuf\Internal\Message */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -105,16 +117,10 @@ class ReservedRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php index f5c7fe1482..85dc246634 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php @@ -20,18 +20,15 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; */ private $value; - private $has_value = false; /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not @@ -40,7 +37,6 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; */ private $reserved_range; - private $has_reserved_range = false; /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. @@ -48,7 +44,6 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated string reserved_name = 5; */ private $reserved_name; - private $has_reserved_name = false; /** * Constructor. @@ -79,7 +74,17 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -91,16 +96,10 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -119,23 +118,27 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class); $this->value = $arr; - $this->has_value = true; return $this; } - public function hasValue() - { - return $this->has_value; - } - /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; * @return \Google\Protobuf\Internal\EnumOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -147,16 +150,10 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not @@ -183,16 +180,10 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class); $this->reserved_range = $arr; - $this->has_reserved_range = true; return $this; } - public function hasReservedRange() - { - return $this->has_reserved_range; - } - /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. @@ -217,15 +208,9 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; - $this->has_reserved_name = true; return $this; } - public function hasReservedName() - { - return $this->has_reserved_name; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php index 949dd89107..7282fccb07 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php @@ -26,15 +26,13 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Inclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -61,7 +59,17 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -75,16 +83,10 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Inclusive. * @@ -93,7 +95,17 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -107,16 +119,10 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php index e6500423b1..7a69676059 100644 --- a/php/src/Google/Protobuf/Internal/EnumOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumOptions.php @@ -21,8 +21,7 @@ class EnumOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool allow_alias = 2; */ - protected $allow_alias = false; - private $has_allow_alias = false; + protected $allow_alias = null; /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -31,15 +30,13 @@ class EnumOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -73,7 +70,17 @@ class EnumOptions extends \Google\Protobuf\Internal\Message */ public function getAllowAlias() { - return $this->allow_alias; + return isset($this->allow_alias) ? $this->allow_alias : false; + } + + public function hasAllowAlias() + { + return isset($this->allow_alias); + } + + public function clearAllowAlias() + { + unset($this->allow_alias); } /** @@ -88,16 +95,10 @@ class EnumOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->allow_alias = $var; - $this->has_allow_alias = true; return $this; } - public function hasAllowAlias() - { - return $this->has_allow_alias; - } - /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -109,7 +110,17 @@ class EnumOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -126,16 +137,10 @@ class EnumOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -158,15 +163,9 @@ class EnumOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php index 3dd95583ac..01097b669d 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php @@ -20,18 +20,15 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional int32 number = 2; */ - protected $number = 0; - private $has_number = false; + protected $number = null; /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -55,7 +52,17 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -67,23 +74,27 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional int32 number = 2; * @return int */ public function getNumber() { - return $this->number; + return isset($this->number) ? $this->number : 0; + } + + public function hasNumber() + { + return isset($this->number); + } + + public function clearNumber() + { + unset($this->number); } /** @@ -95,23 +106,27 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->number = $var; - $this->has_number = true; return $this; } - public function hasNumber() - { - return $this->has_number; - } - /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; * @return \Google\Protobuf\Internal\EnumValueOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -123,15 +138,9 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumValueOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php index 9f9fb3bec1..84ba7bc85b 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php @@ -23,15 +23,13 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 1 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -64,7 +62,17 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -81,16 +89,10 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -113,15 +115,9 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php index 00fbebecaf..b5e27c3e27 100644 --- a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php +++ b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php @@ -21,7 +21,6 @@ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -60,15 +59,9 @@ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index 98b516fecc..ce83f63a2b 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -229,7 +229,17 @@ class FieldDescriptor } $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; - $packed = false; + // TODO: once proto2 is supported, this default should be false + // for proto2. + if ($proto->getLabel() === GPBLabel::REPEATED && + $proto->getType() !== GPBType::MESSAGE && + $proto->getType() !== GPBType::GROUP && + $proto->getType() !== GPBType::STRING && + $proto->getType() !== GPBType::BYTES) { + $packed = true; + } else { + $packed = false; + } $options = $proto->getOptions(); if ($options !== null) { $packed = $options->getPacked(); diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php index a65ce707ec..5c8823f8dc 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php @@ -20,26 +20,22 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional int32 number = 3; */ - protected $number = 0; - private $has_number = false; + protected $number = null; /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; */ - protected $label = 0; - private $has_label = false; + protected $label = null; /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Type type = 5; */ - protected $type = 0; - private $has_type = false; + protected $type = null; /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping @@ -49,16 +45,14 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string type_name = 6; */ - protected $type_name = ''; - private $has_type_name = false; + protected $type_name = null; /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * * Generated from protobuf field optional string extendee = 2; */ - protected $extendee = ''; - private $has_extendee = false; + protected $extendee = null; /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". @@ -68,16 +62,14 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string default_value = 7; */ - protected $default_value = ''; - private $has_default_value = false; + protected $default_value = null; /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * * Generated from protobuf field optional int32 oneof_index = 9; */ - protected $oneof_index = 0; - private $has_oneof_index = false; + protected $oneof_index = null; /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value @@ -86,13 +78,11 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string json_name = 10; */ - protected $json_name = ''; - private $has_json_name = false; + protected $json_name = null; /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; */ protected $options = null; - private $has_options = false; /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. @@ -115,8 +105,7 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool proto3_optional = 17; */ - protected $proto3_optional = false; - private $has_proto3_optional = false; + protected $proto3_optional = null; /** * Constructor. @@ -186,7 +175,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -198,23 +197,27 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional int32 number = 3; * @return int */ public function getNumber() { - return $this->number; + return isset($this->number) ? $this->number : 0; + } + + public function hasNumber() + { + return isset($this->number); + } + + public function clearNumber() + { + unset($this->number); } /** @@ -226,23 +229,27 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->number = $var; - $this->has_number = true; return $this; } - public function hasNumber() - { - return $this->has_number; - } - /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; * @return int */ public function getLabel() { - return $this->label; + return isset($this->label) ? $this->label : 0; + } + + public function hasLabel() + { + return isset($this->label); + } + + public function clearLabel() + { + unset($this->label); } /** @@ -254,16 +261,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Label::class); $this->label = $var; - $this->has_label = true; return $this; } - public function hasLabel() - { - return $this->has_label; - } - /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. @@ -273,7 +274,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getType() { - return $this->type; + return isset($this->type) ? $this->type : 0; + } + + public function hasType() + { + return isset($this->type); + } + + public function clearType() + { + unset($this->type); } /** @@ -288,16 +299,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Type::class); $this->type = $var; - $this->has_type = true; return $this; } - public function hasType() - { - return $this->has_type; - } - /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping @@ -310,7 +315,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getTypeName() { - return $this->type_name; + return isset($this->type_name) ? $this->type_name : ''; + } + + public function hasTypeName() + { + return isset($this->type_name); + } + + public function clearTypeName() + { + unset($this->type_name); } /** @@ -328,16 +343,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->type_name = $var; - $this->has_type_name = true; return $this; } - public function hasTypeName() - { - return $this->has_type_name; - } - /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. @@ -347,7 +356,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getExtendee() { - return $this->extendee; + return isset($this->extendee) ? $this->extendee : ''; + } + + public function hasExtendee() + { + return isset($this->extendee); + } + + public function clearExtendee() + { + unset($this->extendee); } /** @@ -362,16 +381,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->extendee = $var; - $this->has_extendee = true; return $this; } - public function hasExtendee() - { - return $this->has_extendee; - } - /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". @@ -384,7 +397,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getDefaultValue() { - return $this->default_value; + return isset($this->default_value) ? $this->default_value : ''; + } + + public function hasDefaultValue() + { + return isset($this->default_value); + } + + public function clearDefaultValue() + { + unset($this->default_value); } /** @@ -402,16 +425,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->default_value = $var; - $this->has_default_value = true; return $this; } - public function hasDefaultValue() - { - return $this->has_default_value; - } - /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. @@ -421,7 +438,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getOneofIndex() { - return $this->oneof_index; + return isset($this->oneof_index) ? $this->oneof_index : 0; + } + + public function hasOneofIndex() + { + return isset($this->oneof_index); + } + + public function clearOneofIndex() + { + unset($this->oneof_index); } /** @@ -436,16 +463,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->oneof_index = $var; - $this->has_oneof_index = true; return $this; } - public function hasOneofIndex() - { - return $this->has_oneof_index; - } - /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value @@ -457,7 +478,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getJsonName() { - return $this->json_name; + return isset($this->json_name) ? $this->json_name : ''; + } + + public function hasJsonName() + { + return isset($this->json_name); + } + + public function clearJsonName() + { + unset($this->json_name); } /** @@ -474,23 +505,27 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->json_name = $var; - $this->has_json_name = true; return $this; } - public function hasJsonName() - { - return $this->has_json_name; - } - /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; * @return \Google\Protobuf\Internal\FieldOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -502,16 +537,10 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. @@ -537,7 +566,17 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getProto3Optional() { - return $this->proto3_optional; + return isset($this->proto3_optional) ? $this->proto3_optional : false; + } + + public function hasProto3Optional() + { + return isset($this->proto3_optional); + } + + public function clearProto3Optional() + { + unset($this->proto3_optional); } /** @@ -568,15 +607,9 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->proto3_optional = $var; - $this->has_proto3_optional = true; return $this; } - public function hasProto3Optional() - { - return $this->has_proto3_optional; - } - } diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index c57077d858..c6c63a9665 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -23,8 +23,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; */ - protected $ctype = 0; - private $has_ctype = false; + protected $ctype = null; /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly @@ -34,8 +33,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool packed = 2; */ - protected $packed = false; - private $has_packed = false; + protected $packed = null; /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types @@ -50,8 +48,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; */ - protected $jstype = 0; - private $has_jstype = false; + protected $jstype = null; /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the @@ -80,8 +77,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool lazy = 5 [default = false]; */ - protected $lazy = false; - private $has_lazy = false; + protected $lazy = null; /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -90,22 +86,19 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * For Google-internal migration only. Do not use. * * Generated from protobuf field optional bool weak = 10 [default = false]; */ - protected $weak = false; - private $has_weak = false; + protected $weak = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -187,7 +180,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getCtype() { - return $this->ctype; + return isset($this->ctype) ? $this->ctype : 0; + } + + public function hasCtype() + { + return isset($this->ctype); + } + + public function clearCtype() + { + unset($this->ctype); } /** @@ -204,16 +207,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\CType::class); $this->ctype = $var; - $this->has_ctype = true; return $this; } - public function hasCtype() - { - return $this->has_ctype; - } - /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly @@ -226,7 +223,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getPacked() { - return $this->packed; + return isset($this->packed) ? $this->packed : false; + } + + public function hasPacked() + { + return isset($this->packed); + } + + public function clearPacked() + { + unset($this->packed); } /** @@ -244,16 +251,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->packed = $var; - $this->has_packed = true; return $this; } - public function hasPacked() - { - return $this->has_packed; - } - /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types @@ -271,7 +272,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getJstype() { - return $this->jstype; + return isset($this->jstype) ? $this->jstype : 0; + } + + public function hasJstype() + { + return isset($this->jstype); + } + + public function clearJstype() + { + unset($this->jstype); } /** @@ -294,16 +305,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\JSType::class); $this->jstype = $var; - $this->has_jstype = true; return $this; } - public function hasJstype() - { - return $this->has_jstype; - } - /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the @@ -335,7 +340,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getLazy() { - return $this->lazy; + return isset($this->lazy) ? $this->lazy : false; + } + + public function hasLazy() + { + return isset($this->lazy); + } + + public function clearLazy() + { + unset($this->lazy); } /** @@ -372,16 +387,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->lazy = $var; - $this->has_lazy = true; return $this; } - public function hasLazy() - { - return $this->has_lazy; - } - /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -393,7 +402,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -410,16 +429,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * For Google-internal migration only. Do not use. * @@ -428,7 +441,17 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function getWeak() { - return $this->weak; + return isset($this->weak) ? $this->weak : false; + } + + public function hasWeak() + { + return isset($this->weak); + } + + public function clearWeak() + { + unset($this->weak); } /** @@ -442,16 +465,10 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->weak = $var; - $this->has_weak = true; return $this; } - public function hasWeak() - { - return $this->has_weak; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -474,15 +491,9 @@ class FieldOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php index c9e3648c23..96e2c6a6e7 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php @@ -22,29 +22,25 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * e.g. "foo", "foo.bar", etc. * * Generated from protobuf field optional string package = 2; */ - protected $package = ''; - private $has_package = false; + protected $package = null; /** * Names of files imported by this file. * * Generated from protobuf field repeated string dependency = 3; */ private $dependency; - private $has_dependency = false; /** * Indexes of the public imported files in the dependency list above. * * Generated from protobuf field repeated int32 public_dependency = 10; */ private $public_dependency; - private $has_public_dependency = false; /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. @@ -52,34 +48,28 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 weak_dependency = 11; */ private $weak_dependency; - private $has_weak_dependency = false; /** * All top-level definitions in this file. * * Generated from protobuf field repeated .google.protobuf.DescriptorProto message_type = 4; */ private $message_type; - private $has_message_type = false; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; */ private $enum_type; - private $has_enum_type = false; /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; */ private $service; - private $has_service = false; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; */ private $extension; - private $has_extension = false; /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; */ protected $options = null; - private $has_options = false; /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime @@ -89,15 +79,13 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field optional .google.protobuf.SourceCodeInfo source_code_info = 9; */ protected $source_code_info = null; - private $has_source_code_info = false; /** * The syntax of the proto file. * The supported values are "proto2" and "proto3". * * Generated from protobuf field optional string syntax = 12; */ - protected $syntax = ''; - private $has_syntax = false; + protected $syntax = null; /** * Constructor. @@ -145,7 +133,17 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -159,16 +157,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * e.g. "foo", "foo.bar", etc. * @@ -177,7 +169,17 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getPackage() { - return $this->package; + return isset($this->package) ? $this->package : ''; + } + + public function hasPackage() + { + return isset($this->package); + } + + public function clearPackage() + { + unset($this->package); } /** @@ -191,16 +193,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->package = $var; - $this->has_package = true; return $this; } - public function hasPackage() - { - return $this->has_package; - } - /** * Names of files imported by this file. * @@ -223,16 +219,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->dependency = $arr; - $this->has_dependency = true; return $this; } - public function hasDependency() - { - return $this->has_dependency; - } - /** * Indexes of the public imported files in the dependency list above. * @@ -255,16 +245,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->public_dependency = $arr; - $this->has_public_dependency = true; return $this; } - public function hasPublicDependency() - { - return $this->has_public_dependency; - } - /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. @@ -289,16 +273,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->weak_dependency = $arr; - $this->has_weak_dependency = true; return $this; } - public function hasWeakDependency() - { - return $this->has_weak_dependency; - } - /** * All top-level definitions in this file. * @@ -321,16 +299,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->message_type = $arr; - $this->has_message_type = true; return $this; } - public function hasMessageType() - { - return $this->has_message_type; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; * @return \Google\Protobuf\Internal\RepeatedField @@ -349,16 +321,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; - $this->has_enum_type = true; return $this; } - public function hasEnumType() - { - return $this->has_enum_type; - } - /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -377,16 +343,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class); $this->service = $arr; - $this->has_service = true; return $this; } - public function hasService() - { - return $this->has_service; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; * @return \Google\Protobuf\Internal\RepeatedField @@ -405,23 +365,27 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; - $this->has_extension = true; return $this; } - public function hasExtension() - { - return $this->has_extension; - } - /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; * @return \Google\Protobuf\Internal\FileOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -433,16 +397,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FileOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime @@ -454,7 +412,17 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getSourceCodeInfo() { - return $this->source_code_info; + return isset($this->source_code_info) ? $this->source_code_info : null; + } + + public function hasSourceCodeInfo() + { + return isset($this->source_code_info); + } + + public function clearSourceCodeInfo() + { + unset($this->source_code_info); } /** @@ -471,16 +439,10 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\SourceCodeInfo::class); $this->source_code_info = $var; - $this->has_source_code_info = true; return $this; } - public function hasSourceCodeInfo() - { - return $this->has_source_code_info; - } - /** * The syntax of the proto file. * The supported values are "proto2" and "proto3". @@ -490,7 +452,17 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getSyntax() { - return $this->syntax; + return isset($this->syntax) ? $this->syntax : ''; + } + + public function hasSyntax() + { + return isset($this->syntax); + } + + public function clearSyntax() + { + unset($this->syntax); } /** @@ -505,15 +477,9 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->syntax = $var; - $this->has_syntax = true; return $this; } - public function hasSyntax() - { - return $this->has_syntax; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php index 9907b17d73..794e6347a3 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php @@ -22,7 +22,6 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.FileDescriptorProto file = 1; */ private $file; - private $has_file = false; /** * Constructor. @@ -56,15 +55,9 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class); $this->file = $arr; - $this->has_file = true; return $this; } - public function hasFile() - { - return $this->has_file; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php index 666c6c9075..f415b07f2c 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions.php +++ b/php/src/Google/Protobuf/Internal/FileOptions.php @@ -23,8 +23,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string java_package = 1; */ - protected $java_package = ''; - private $has_java_package = false; + protected $java_package = null; /** * If set, all the classes from the .proto file are wrapped in a single * outer class with the given name. This applies to both Proto1 @@ -34,8 +33,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string java_outer_classname = 8; */ - protected $java_outer_classname = ''; - private $has_java_outer_classname = false; + protected $java_outer_classname = null; /** * If set true, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto @@ -46,15 +44,13 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool java_multiple_files = 10 [default = false]; */ - protected $java_multiple_files = false; - private $has_java_multiple_files = false; + protected $java_multiple_files = null; /** * This option does nothing. * * Generated from protobuf field optional bool java_generate_equals_and_hash = 20 [deprecated = true]; */ - protected $java_generate_equals_and_hash = false; - private $has_java_generate_equals_and_hash = false; + protected $java_generate_equals_and_hash = null; /** * If set true, then the Java2 code generator will generate code that * throws an exception whenever an attempt is made to assign a non-UTF-8 @@ -65,13 +61,11 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool java_string_check_utf8 = 27 [default = false]; */ - protected $java_string_check_utf8 = false; - private $has_java_string_check_utf8 = false; + protected $java_string_check_utf8 = null; /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; */ - protected $optimize_for = 0; - private $has_optimize_for = false; + protected $optimize_for = null; /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: @@ -81,8 +75,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string go_package = 11; */ - protected $go_package = ''; - private $has_go_package = false; + protected $go_package = null; /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the @@ -96,23 +89,19 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool cc_generic_services = 16 [default = false]; */ - protected $cc_generic_services = false; - private $has_cc_generic_services = false; + protected $cc_generic_services = null; /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; */ - protected $java_generic_services = false; - private $has_java_generic_services = false; + protected $java_generic_services = null; /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; */ - protected $py_generic_services = false; - private $has_py_generic_services = false; + protected $py_generic_services = null; /** * Generated from protobuf field optional bool php_generic_services = 42 [default = false]; */ - protected $php_generic_services = false; - private $has_php_generic_services = false; + protected $php_generic_services = null; /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -121,31 +110,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 23 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; */ - protected $cc_enable_arenas = false; - private $has_cc_enable_arenas = false; + protected $cc_enable_arenas = null; /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * * Generated from protobuf field optional string objc_class_prefix = 36; */ - protected $objc_class_prefix = ''; - private $has_objc_class_prefix = false; + protected $objc_class_prefix = null; /** * Namespace for generated classes; defaults to the package. * * Generated from protobuf field optional string csharp_namespace = 37; */ - protected $csharp_namespace = ''; - private $has_csharp_namespace = false; + protected $csharp_namespace = null; /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols @@ -154,16 +139,14 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string swift_prefix = 39; */ - protected $swift_prefix = ''; - private $has_swift_prefix = false; + protected $swift_prefix = null; /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * * Generated from protobuf field optional string php_class_prefix = 40; */ - protected $php_class_prefix = ''; - private $has_php_class_prefix = false; + protected $php_class_prefix = null; /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for @@ -171,8 +154,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string php_namespace = 41; */ - protected $php_namespace = ''; - private $has_php_namespace = false; + protected $php_namespace = null; /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be @@ -180,8 +162,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string php_metadata_namespace = 44; */ - protected $php_metadata_namespace = ''; - private $has_php_metadata_namespace = false; + protected $php_metadata_namespace = null; /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for @@ -189,8 +170,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string ruby_package = 45; */ - protected $ruby_package = ''; - private $has_ruby_package = false; + protected $ruby_package = null; /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. @@ -198,7 +178,6 @@ class FileOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -307,7 +286,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getJavaPackage() { - return $this->java_package; + return isset($this->java_package) ? $this->java_package : ''; + } + + public function hasJavaPackage() + { + return isset($this->java_package); + } + + public function clearJavaPackage() + { + unset($this->java_package); } /** @@ -324,16 +313,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->java_package = $var; - $this->has_java_package = true; return $this; } - public function hasJavaPackage() - { - return $this->has_java_package; - } - /** * If set, all the classes from the .proto file are wrapped in a single * outer class with the given name. This applies to both Proto1 @@ -346,7 +329,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getJavaOuterClassname() { - return $this->java_outer_classname; + return isset($this->java_outer_classname) ? $this->java_outer_classname : ''; + } + + public function hasJavaOuterClassname() + { + return isset($this->java_outer_classname); + } + + public function clearJavaOuterClassname() + { + unset($this->java_outer_classname); } /** @@ -364,16 +357,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->java_outer_classname = $var; - $this->has_java_outer_classname = true; return $this; } - public function hasJavaOuterClassname() - { - return $this->has_java_outer_classname; - } - /** * If set true, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto @@ -387,7 +374,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getJavaMultipleFiles() { - return $this->java_multiple_files; + return isset($this->java_multiple_files) ? $this->java_multiple_files : false; + } + + public function hasJavaMultipleFiles() + { + return isset($this->java_multiple_files); + } + + public function clearJavaMultipleFiles() + { + unset($this->java_multiple_files); } /** @@ -406,16 +403,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->java_multiple_files = $var; - $this->has_java_multiple_files = true; return $this; } - public function hasJavaMultipleFiles() - { - return $this->has_java_multiple_files; - } - /** * This option does nothing. * @@ -424,7 +415,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getJavaGenerateEqualsAndHash() { - return $this->java_generate_equals_and_hash; + return isset($this->java_generate_equals_and_hash) ? $this->java_generate_equals_and_hash : false; + } + + public function hasJavaGenerateEqualsAndHash() + { + return isset($this->java_generate_equals_and_hash); + } + + public function clearJavaGenerateEqualsAndHash() + { + unset($this->java_generate_equals_and_hash); } /** @@ -438,16 +439,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->java_generate_equals_and_hash = $var; - $this->has_java_generate_equals_and_hash = true; return $this; } - public function hasJavaGenerateEqualsAndHash() - { - return $this->has_java_generate_equals_and_hash; - } - /** * If set true, then the Java2 code generator will generate code that * throws an exception whenever an attempt is made to assign a non-UTF-8 @@ -461,7 +456,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getJavaStringCheckUtf8() { - return $this->java_string_check_utf8; + return isset($this->java_string_check_utf8) ? $this->java_string_check_utf8 : false; + } + + public function hasJavaStringCheckUtf8() + { + return isset($this->java_string_check_utf8); + } + + public function clearJavaStringCheckUtf8() + { + unset($this->java_string_check_utf8); } /** @@ -480,23 +485,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->java_string_check_utf8 = $var; - $this->has_java_string_check_utf8 = true; return $this; } - public function hasJavaStringCheckUtf8() - { - return $this->has_java_string_check_utf8; - } - /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; * @return int */ public function getOptimizeFor() { - return $this->optimize_for; + return isset($this->optimize_for) ? $this->optimize_for : 0; + } + + public function hasOptimizeFor() + { + return isset($this->optimize_for); + } + + public function clearOptimizeFor() + { + unset($this->optimize_for); } /** @@ -508,16 +517,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions\OptimizeMode::class); $this->optimize_for = $var; - $this->has_optimize_for = true; return $this; } - public function hasOptimizeFor() - { - return $this->has_optimize_for; - } - /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: @@ -530,7 +533,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getGoPackage() { - return $this->go_package; + return isset($this->go_package) ? $this->go_package : ''; + } + + public function hasGoPackage() + { + return isset($this->go_package); + } + + public function clearGoPackage() + { + unset($this->go_package); } /** @@ -548,16 +561,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->go_package = $var; - $this->has_go_package = true; return $this; } - public function hasGoPackage() - { - return $this->has_go_package; - } - /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the @@ -574,7 +581,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getCcGenericServices() { - return $this->cc_generic_services; + return isset($this->cc_generic_services) ? $this->cc_generic_services : false; + } + + public function hasCcGenericServices() + { + return isset($this->cc_generic_services); + } + + public function clearCcGenericServices() + { + unset($this->cc_generic_services); } /** @@ -596,23 +613,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->cc_generic_services = $var; - $this->has_cc_generic_services = true; return $this; } - public function hasCcGenericServices() - { - return $this->has_cc_generic_services; - } - /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; * @return bool */ public function getJavaGenericServices() { - return $this->java_generic_services; + return isset($this->java_generic_services) ? $this->java_generic_services : false; + } + + public function hasJavaGenericServices() + { + return isset($this->java_generic_services); + } + + public function clearJavaGenericServices() + { + unset($this->java_generic_services); } /** @@ -624,23 +645,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->java_generic_services = $var; - $this->has_java_generic_services = true; return $this; } - public function hasJavaGenericServices() - { - return $this->has_java_generic_services; - } - /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; * @return bool */ public function getPyGenericServices() { - return $this->py_generic_services; + return isset($this->py_generic_services) ? $this->py_generic_services : false; + } + + public function hasPyGenericServices() + { + return isset($this->py_generic_services); + } + + public function clearPyGenericServices() + { + unset($this->py_generic_services); } /** @@ -652,23 +677,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->py_generic_services = $var; - $this->has_py_generic_services = true; return $this; } - public function hasPyGenericServices() - { - return $this->has_py_generic_services; - } - /** * Generated from protobuf field optional bool php_generic_services = 42 [default = false]; * @return bool */ public function getPhpGenericServices() { - return $this->php_generic_services; + return isset($this->php_generic_services) ? $this->php_generic_services : false; + } + + public function hasPhpGenericServices() + { + return isset($this->php_generic_services); + } + + public function clearPhpGenericServices() + { + unset($this->php_generic_services); } /** @@ -680,16 +709,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->php_generic_services = $var; - $this->has_php_generic_services = true; return $this; } - public function hasPhpGenericServices() - { - return $this->has_php_generic_services; - } - /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -701,7 +724,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -718,16 +751,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. @@ -737,7 +764,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getCcEnableArenas() { - return $this->cc_enable_arenas; + return isset($this->cc_enable_arenas) ? $this->cc_enable_arenas : false; + } + + public function hasCcEnableArenas() + { + return isset($this->cc_enable_arenas); + } + + public function clearCcEnableArenas() + { + unset($this->cc_enable_arenas); } /** @@ -752,16 +789,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->cc_enable_arenas = $var; - $this->has_cc_enable_arenas = true; return $this; } - public function hasCcEnableArenas() - { - return $this->has_cc_enable_arenas; - } - /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. @@ -771,7 +802,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getObjcClassPrefix() { - return $this->objc_class_prefix; + return isset($this->objc_class_prefix) ? $this->objc_class_prefix : ''; + } + + public function hasObjcClassPrefix() + { + return isset($this->objc_class_prefix); + } + + public function clearObjcClassPrefix() + { + unset($this->objc_class_prefix); } /** @@ -786,16 +827,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->objc_class_prefix = $var; - $this->has_objc_class_prefix = true; return $this; } - public function hasObjcClassPrefix() - { - return $this->has_objc_class_prefix; - } - /** * Namespace for generated classes; defaults to the package. * @@ -804,7 +839,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getCsharpNamespace() { - return $this->csharp_namespace; + return isset($this->csharp_namespace) ? $this->csharp_namespace : ''; + } + + public function hasCsharpNamespace() + { + return isset($this->csharp_namespace); + } + + public function clearCsharpNamespace() + { + unset($this->csharp_namespace); } /** @@ -818,16 +863,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->csharp_namespace = $var; - $this->has_csharp_namespace = true; return $this; } - public function hasCsharpNamespace() - { - return $this->has_csharp_namespace; - } - /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols @@ -839,7 +878,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getSwiftPrefix() { - return $this->swift_prefix; + return isset($this->swift_prefix) ? $this->swift_prefix : ''; + } + + public function hasSwiftPrefix() + { + return isset($this->swift_prefix); + } + + public function clearSwiftPrefix() + { + unset($this->swift_prefix); } /** @@ -856,16 +905,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->swift_prefix = $var; - $this->has_swift_prefix = true; return $this; } - public function hasSwiftPrefix() - { - return $this->has_swift_prefix; - } - /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. @@ -875,7 +918,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getPhpClassPrefix() { - return $this->php_class_prefix; + return isset($this->php_class_prefix) ? $this->php_class_prefix : ''; + } + + public function hasPhpClassPrefix() + { + return isset($this->php_class_prefix); + } + + public function clearPhpClassPrefix() + { + unset($this->php_class_prefix); } /** @@ -890,16 +943,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->php_class_prefix = $var; - $this->has_php_class_prefix = true; return $this; } - public function hasPhpClassPrefix() - { - return $this->has_php_class_prefix; - } - /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for @@ -910,7 +957,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getPhpNamespace() { - return $this->php_namespace; + return isset($this->php_namespace) ? $this->php_namespace : ''; + } + + public function hasPhpNamespace() + { + return isset($this->php_namespace); + } + + public function clearPhpNamespace() + { + unset($this->php_namespace); } /** @@ -926,16 +983,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->php_namespace = $var; - $this->has_php_namespace = true; return $this; } - public function hasPhpNamespace() - { - return $this->has_php_namespace; - } - /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be @@ -946,7 +997,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getPhpMetadataNamespace() { - return $this->php_metadata_namespace; + return isset($this->php_metadata_namespace) ? $this->php_metadata_namespace : ''; + } + + public function hasPhpMetadataNamespace() + { + return isset($this->php_metadata_namespace); + } + + public function clearPhpMetadataNamespace() + { + unset($this->php_metadata_namespace); } /** @@ -962,16 +1023,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->php_metadata_namespace = $var; - $this->has_php_metadata_namespace = true; return $this; } - public function hasPhpMetadataNamespace() - { - return $this->has_php_metadata_namespace; - } - /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for @@ -982,7 +1037,17 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function getRubyPackage() { - return $this->ruby_package; + return isset($this->ruby_package) ? $this->ruby_package : ''; + } + + public function hasRubyPackage() + { + return isset($this->ruby_package); + } + + public function clearRubyPackage() + { + unset($this->ruby_package); } /** @@ -998,16 +1063,10 @@ class FileOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->ruby_package = $var; - $this->has_ruby_package = true; return $this; } - public function hasRubyPackage() - { - return $this->has_ruby_package; - } - /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. @@ -1032,15 +1091,9 @@ class FileOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php index f5a65bea46..c261ed6ec9 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php @@ -26,7 +26,6 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; */ private $annotation; - private $has_annotation = false; /** * Constructor. @@ -68,15 +67,9 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class); $this->annotation = $arr; - $this->has_annotation = true; return $this; } - public function hasAnnotation() - { - return $this->has_annotation; - } - } diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php index 369fea4892..0b043d0665 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php @@ -22,22 +22,19 @@ class Annotation extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; - private $has_path = false; /** * Identifies the filesystem path to the original source .proto. * * Generated from protobuf field optional string source_file = 2; */ - protected $source_file = ''; - private $has_source_file = false; + protected $source_file = null; /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * * Generated from protobuf field optional int32 begin = 3; */ - protected $begin = 0; - private $has_begin = false; + protected $begin = null; /** * Identifies the ending offset in bytes in the generated code that * relates to the identified offset. The end offset should be one past @@ -45,8 +42,7 @@ class Annotation extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 end = 4; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -97,16 +93,10 @@ class Annotation extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; - $this->has_path = true; return $this; } - public function hasPath() - { - return $this->has_path; - } - /** * Identifies the filesystem path to the original source .proto. * @@ -115,7 +105,17 @@ class Annotation extends \Google\Protobuf\Internal\Message */ public function getSourceFile() { - return $this->source_file; + return isset($this->source_file) ? $this->source_file : ''; + } + + public function hasSourceFile() + { + return isset($this->source_file); + } + + public function clearSourceFile() + { + unset($this->source_file); } /** @@ -129,16 +129,10 @@ class Annotation extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->source_file = $var; - $this->has_source_file = true; return $this; } - public function hasSourceFile() - { - return $this->has_source_file; - } - /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. @@ -148,7 +142,17 @@ class Annotation extends \Google\Protobuf\Internal\Message */ public function getBegin() { - return $this->begin; + return isset($this->begin) ? $this->begin : 0; + } + + public function hasBegin() + { + return isset($this->begin); + } + + public function clearBegin() + { + unset($this->begin); } /** @@ -163,16 +167,10 @@ class Annotation extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->begin = $var; - $this->has_begin = true; return $this; } - public function hasBegin() - { - return $this->has_begin; - } - /** * Identifies the ending offset in bytes in the generated code that * relates to the identified offset. The end offset should be one past @@ -183,7 +181,17 @@ class Annotation extends \Google\Protobuf\Internal\Message */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -199,16 +207,10 @@ class Annotation extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 77614bc0e9..c02d2b4517 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -225,6 +225,15 @@ class Message } } + protected function hasOneof($number) + { + $field = $this->desc->getFieldByNumber($number); + $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; + $oneof_name = $oneof->getName(); + $oneof_field = $this->$oneof_name; + return $number === $oneof_field->getNumber(); + } + protected function writeOneof($number, $value) { $field = $this->desc->getFieldByNumber($number); @@ -1559,14 +1568,19 @@ class Message */ private function existField($field) { - $oneof_index = $field->getOneofIndex(); - if ($oneof_index !== -1) { - $oneof = $this->desc->getOneofDecl()[$oneof_index]; - $oneof_name = $oneof->getName(); - return $this->$oneof_name->getNumber() === $field->getNumber(); + $getter = $field->getGetter(); + $hazzer = "has" . substr($getter, 3); + + if (method_exists($this, $hazzer)) { + return $this->$hazzer(); + } else if ($field->getOneofIndex() !== -1) { + // For old generated code, which does not have hazzers for oneof + // fields. + $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; + $oneof_name = $oneof->getName(); + return $this->$oneof_name->getNumber() === $field->getNumber(); } - $getter = $field->getGetter(); $values = $this->$getter(); if ($field->isMap()) { return count($values) !== 0; diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php index 95bb706a5a..2f4e3cb7f4 100644 --- a/php/src/Google/Protobuf/Internal/MessageOptions.php +++ b/php/src/Google/Protobuf/Internal/MessageOptions.php @@ -34,8 +34,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool message_set_wire_format = 1 [default = false]; */ - protected $message_set_wire_format = false; - private $has_message_set_wire_format = false; + protected $message_set_wire_format = null; /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration @@ -43,8 +42,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool no_standard_descriptor_accessor = 2 [default = false]; */ - protected $no_standard_descriptor_accessor = false; - private $has_no_standard_descriptor_accessor = false; + protected $no_standard_descriptor_accessor = null; /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -53,8 +51,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Whether the message is an automatically generated map entry type for the * maps field. @@ -77,15 +74,13 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool map_entry = 7; */ - protected $map_entry = false; - private $has_map_entry = false; + protected $map_entry = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -168,7 +163,17 @@ class MessageOptions extends \Google\Protobuf\Internal\Message */ public function getMessageSetWireFormat() { - return $this->message_set_wire_format; + return isset($this->message_set_wire_format) ? $this->message_set_wire_format : false; + } + + public function hasMessageSetWireFormat() + { + return isset($this->message_set_wire_format); + } + + public function clearMessageSetWireFormat() + { + unset($this->message_set_wire_format); } /** @@ -196,16 +201,10 @@ class MessageOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->message_set_wire_format = $var; - $this->has_message_set_wire_format = true; return $this; } - public function hasMessageSetWireFormat() - { - return $this->has_message_set_wire_format; - } - /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration @@ -216,7 +215,17 @@ class MessageOptions extends \Google\Protobuf\Internal\Message */ public function getNoStandardDescriptorAccessor() { - return $this->no_standard_descriptor_accessor; + return isset($this->no_standard_descriptor_accessor) ? $this->no_standard_descriptor_accessor : false; + } + + public function hasNoStandardDescriptorAccessor() + { + return isset($this->no_standard_descriptor_accessor); + } + + public function clearNoStandardDescriptorAccessor() + { + unset($this->no_standard_descriptor_accessor); } /** @@ -232,16 +241,10 @@ class MessageOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->no_standard_descriptor_accessor = $var; - $this->has_no_standard_descriptor_accessor = true; return $this; } - public function hasNoStandardDescriptorAccessor() - { - return $this->has_no_standard_descriptor_accessor; - } - /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -253,7 +256,17 @@ class MessageOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -270,16 +283,10 @@ class MessageOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Whether the message is an automatically generated map entry type for the * maps field. @@ -305,7 +312,17 @@ class MessageOptions extends \Google\Protobuf\Internal\Message */ public function getMapEntry() { - return $this->map_entry; + return isset($this->map_entry) ? $this->map_entry : false; + } + + public function hasMapEntry() + { + return isset($this->map_entry); + } + + public function clearMapEntry() + { + unset($this->map_entry); } /** @@ -336,16 +353,10 @@ class MessageOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->map_entry = $var; - $this->has_map_entry = true; return $this; } - public function hasMapEntry() - { - return $this->has_map_entry; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -368,15 +379,9 @@ class MessageOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php index f40f20f0d7..e2ea8ea6c5 100644 --- a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php @@ -20,40 +20,34 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * * Generated from protobuf field optional string input_type = 2; */ - protected $input_type = ''; - private $has_input_type = false; + protected $input_type = null; /** * Generated from protobuf field optional string output_type = 3; */ - protected $output_type = ''; - private $has_output_type = false; + protected $output_type = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; */ protected $options = null; - private $has_options = false; /** * Identifies if client streams multiple client messages * * Generated from protobuf field optional bool client_streaming = 5 [default = false]; */ - protected $client_streaming = false; - private $has_client_streaming = false; + protected $client_streaming = null; /** * Identifies if server streams multiple server messages * * Generated from protobuf field optional bool server_streaming = 6 [default = false]; */ - protected $server_streaming = false; - private $has_server_streaming = false; + protected $server_streaming = null; /** * Constructor. @@ -84,7 +78,17 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -96,16 +100,10 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. @@ -115,7 +113,17 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getInputType() { - return $this->input_type; + return isset($this->input_type) ? $this->input_type : ''; + } + + public function hasInputType() + { + return isset($this->input_type); + } + + public function clearInputType() + { + unset($this->input_type); } /** @@ -130,23 +138,27 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->input_type = $var; - $this->has_input_type = true; return $this; } - public function hasInputType() - { - return $this->has_input_type; - } - /** * Generated from protobuf field optional string output_type = 3; * @return string */ public function getOutputType() { - return $this->output_type; + return isset($this->output_type) ? $this->output_type : ''; + } + + public function hasOutputType() + { + return isset($this->output_type); + } + + public function clearOutputType() + { + unset($this->output_type); } /** @@ -158,23 +170,27 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->output_type = $var; - $this->has_output_type = true; return $this; } - public function hasOutputType() - { - return $this->has_output_type; - } - /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; * @return \Google\Protobuf\Internal\MethodOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -186,16 +202,10 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MethodOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Identifies if client streams multiple client messages * @@ -204,7 +214,17 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getClientStreaming() { - return $this->client_streaming; + return isset($this->client_streaming) ? $this->client_streaming : false; + } + + public function hasClientStreaming() + { + return isset($this->client_streaming); + } + + public function clearClientStreaming() + { + unset($this->client_streaming); } /** @@ -218,16 +238,10 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->client_streaming = $var; - $this->has_client_streaming = true; return $this; } - public function hasClientStreaming() - { - return $this->has_client_streaming; - } - /** * Identifies if server streams multiple server messages * @@ -236,7 +250,17 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getServerStreaming() { - return $this->server_streaming; + return isset($this->server_streaming) ? $this->server_streaming : false; + } + + public function hasServerStreaming() + { + return isset($this->server_streaming); + } + + public function clearServerStreaming() + { + unset($this->server_streaming); } /** @@ -250,15 +274,9 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->server_streaming = $var; - $this->has_server_streaming = true; return $this; } - public function hasServerStreaming() - { - return $this->has_server_streaming; - } - } diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php index f96dd3c22c..a4595b7448 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions.php @@ -23,20 +23,17 @@ class MethodOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; */ - protected $idempotency_level = 0; - private $has_idempotency_level = false; + protected $idempotency_level = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -70,7 +67,17 @@ class MethodOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -87,23 +94,27 @@ class MethodOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; * @return int */ public function getIdempotencyLevel() { - return $this->idempotency_level; + return isset($this->idempotency_level) ? $this->idempotency_level : 0; + } + + public function hasIdempotencyLevel() + { + return isset($this->idempotency_level); + } + + public function clearIdempotencyLevel() + { + unset($this->idempotency_level); } /** @@ -115,16 +126,10 @@ class MethodOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel::class); $this->idempotency_level = $var; - $this->has_idempotency_level = true; return $this; } - public function hasIdempotencyLevel() - { - return $this->has_idempotency_level; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -147,15 +152,9 @@ class MethodOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php index 413b8e55eb..5ae36ce7d5 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php @@ -20,13 +20,11 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -49,7 +47,17 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -61,23 +69,27 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; * @return \Google\Protobuf\Internal\OneofOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -89,15 +101,9 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\OneofOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php index 46b516f301..8dde8f3b17 100644 --- a/php/src/Google/Protobuf/Internal/OneofOptions.php +++ b/php/src/Google/Protobuf/Internal/OneofOptions.php @@ -21,7 +21,6 @@ class OneofOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -60,15 +59,9 @@ class OneofOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php index aaeefbc9ea..9c2cc8fc90 100644 --- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php @@ -20,18 +20,15 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; */ private $method; - private $has_method = false; /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -55,7 +52,17 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -67,16 +74,10 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -95,23 +96,27 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class); $this->method = $arr; - $this->has_method = true; return $this; } - public function hasMethod() - { - return $this->has_method; - } - /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; * @return \Google\Protobuf\Internal\ServiceOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -123,15 +128,9 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ServiceOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php index 0581efbafc..d15a36ae0a 100644 --- a/php/src/Google/Protobuf/Internal/ServiceOptions.php +++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php @@ -23,15 +23,13 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -64,7 +62,17 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -81,16 +89,10 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -113,15 +115,9 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php index dfeb69ff69..1c572e75eb 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php @@ -64,7 +64,6 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; */ private $location; - private $has_location = false; /** * Constructor. @@ -223,15 +222,9 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo\Location::class); $this->location = $arr; - $this->has_location = true; return $this; } - public function hasLocation() - { - return $this->has_location; - } - } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php index 0aeea61cae..c4cc667e3a 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php @@ -41,7 +41,6 @@ class Location extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; - private $has_path = false; /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. @@ -52,7 +51,6 @@ class Location extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 span = 2 [packed = true]; */ private $span; - private $has_span = false; /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be @@ -93,18 +91,15 @@ class Location extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string leading_comments = 3; */ - protected $leading_comments = ''; - private $has_leading_comments = false; + protected $leading_comments = null; /** * Generated from protobuf field optional string trailing_comments = 4; */ - protected $trailing_comments = ''; - private $has_trailing_comments = false; + protected $trailing_comments = null; /** * Generated from protobuf field repeated string leading_detached_comments = 6; */ private $leading_detached_comments; - private $has_leading_detached_comments = false; /** * Constructor. @@ -248,16 +243,10 @@ class Location extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; - $this->has_path = true; return $this; } - public function hasPath() - { - return $this->has_path; - } - /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. @@ -288,16 +277,10 @@ class Location extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->span = $arr; - $this->has_span = true; return $this; } - public function hasSpan() - { - return $this->has_span; - } - /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be @@ -341,7 +324,17 @@ class Location extends \Google\Protobuf\Internal\Message */ public function getLeadingComments() { - return $this->leading_comments; + return isset($this->leading_comments) ? $this->leading_comments : ''; + } + + public function hasLeadingComments() + { + return isset($this->leading_comments); + } + + public function clearLeadingComments() + { + unset($this->leading_comments); } /** @@ -390,23 +383,27 @@ class Location extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->leading_comments = $var; - $this->has_leading_comments = true; return $this; } - public function hasLeadingComments() - { - return $this->has_leading_comments; - } - /** * Generated from protobuf field optional string trailing_comments = 4; * @return string */ public function getTrailingComments() { - return $this->trailing_comments; + return isset($this->trailing_comments) ? $this->trailing_comments : ''; + } + + public function hasTrailingComments() + { + return isset($this->trailing_comments); + } + + public function clearTrailingComments() + { + unset($this->trailing_comments); } /** @@ -418,16 +415,10 @@ class Location extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->trailing_comments = $var; - $this->has_trailing_comments = true; return $this; } - public function hasTrailingComments() - { - return $this->has_trailing_comments; - } - /** * Generated from protobuf field repeated string leading_detached_comments = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -446,16 +437,10 @@ class Location extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->leading_detached_comments = $arr; - $this->has_leading_detached_comments = true; return $this; } - public function hasLeadingDetachedComments() - { - return $this->has_leading_detached_comments; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php index 6c871cc1ae..a2aae3e0a7 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php @@ -26,40 +26,33 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; */ private $name; - private $has_name = false; /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * * Generated from protobuf field optional string identifier_value = 3; */ - protected $identifier_value = ''; - private $has_identifier_value = false; + protected $identifier_value = null; /** * Generated from protobuf field optional uint64 positive_int_value = 4; */ - protected $positive_int_value = 0; - private $has_positive_int_value = false; + protected $positive_int_value = null; /** * Generated from protobuf field optional int64 negative_int_value = 5; */ - protected $negative_int_value = 0; - private $has_negative_int_value = false; + protected $negative_int_value = null; /** * Generated from protobuf field optional double double_value = 6; */ - protected $double_value = 0.0; - private $has_double_value = false; + protected $double_value = null; /** * Generated from protobuf field optional bytes string_value = 7; */ - protected $string_value = ''; - private $has_string_value = false; + protected $string_value = null; /** * Generated from protobuf field optional string aggregate_value = 8; */ - protected $aggregate_value = ''; - private $has_aggregate_value = false; + protected $aggregate_value = null; /** * Constructor. @@ -101,16 +94,10 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption\NamePart::class); $this->name = $arr; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. @@ -120,7 +107,17 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message */ public function getIdentifierValue() { - return $this->identifier_value; + return isset($this->identifier_value) ? $this->identifier_value : ''; + } + + public function hasIdentifierValue() + { + return isset($this->identifier_value); + } + + public function clearIdentifierValue() + { + unset($this->identifier_value); } /** @@ -135,23 +132,27 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->identifier_value = $var; - $this->has_identifier_value = true; return $this; } - public function hasIdentifierValue() - { - return $this->has_identifier_value; - } - /** * Generated from protobuf field optional uint64 positive_int_value = 4; * @return int|string */ public function getPositiveIntValue() { - return $this->positive_int_value; + return isset($this->positive_int_value) ? $this->positive_int_value : 0; + } + + public function hasPositiveIntValue() + { + return isset($this->positive_int_value); + } + + public function clearPositiveIntValue() + { + unset($this->positive_int_value); } /** @@ -163,23 +164,27 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkUint64($var); $this->positive_int_value = $var; - $this->has_positive_int_value = true; return $this; } - public function hasPositiveIntValue() - { - return $this->has_positive_int_value; - } - /** * Generated from protobuf field optional int64 negative_int_value = 5; * @return int|string */ public function getNegativeIntValue() { - return $this->negative_int_value; + return isset($this->negative_int_value) ? $this->negative_int_value : 0; + } + + public function hasNegativeIntValue() + { + return isset($this->negative_int_value); + } + + public function clearNegativeIntValue() + { + unset($this->negative_int_value); } /** @@ -191,23 +196,27 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkInt64($var); $this->negative_int_value = $var; - $this->has_negative_int_value = true; return $this; } - public function hasNegativeIntValue() - { - return $this->has_negative_int_value; - } - /** * Generated from protobuf field optional double double_value = 6; * @return float */ public function getDoubleValue() { - return $this->double_value; + return isset($this->double_value) ? $this->double_value : 0.0; + } + + public function hasDoubleValue() + { + return isset($this->double_value); + } + + public function clearDoubleValue() + { + unset($this->double_value); } /** @@ -219,23 +228,27 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkDouble($var); $this->double_value = $var; - $this->has_double_value = true; return $this; } - public function hasDoubleValue() - { - return $this->has_double_value; - } - /** * Generated from protobuf field optional bytes string_value = 7; * @return string */ public function getStringValue() { - return $this->string_value; + return isset($this->string_value) ? $this->string_value : ''; + } + + public function hasStringValue() + { + return isset($this->string_value); + } + + public function clearStringValue() + { + unset($this->string_value); } /** @@ -247,23 +260,27 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, False); $this->string_value = $var; - $this->has_string_value = true; return $this; } - public function hasStringValue() - { - return $this->has_string_value; - } - /** * Generated from protobuf field optional string aggregate_value = 8; * @return string */ public function getAggregateValue() { - return $this->aggregate_value; + return isset($this->aggregate_value) ? $this->aggregate_value : ''; + } + + public function hasAggregateValue() + { + return isset($this->aggregate_value); + } + + public function clearAggregateValue() + { + unset($this->aggregate_value); } /** @@ -275,15 +292,9 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->aggregate_value = $var; - $this->has_aggregate_value = true; return $this; } - public function hasAggregateValue() - { - return $this->has_aggregate_value; - } - } diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php index 1956ba7f08..6212d1e457 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php @@ -24,13 +24,11 @@ class NamePart extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field required string name_part = 1; */ - protected $name_part = ''; - private $has_name_part = false; + protected $name_part = null; /** * Generated from protobuf field required bool is_extension = 2; */ - protected $is_extension = false; - private $has_is_extension = false; + protected $is_extension = null; /** * Constructor. @@ -53,7 +51,17 @@ class NamePart extends \Google\Protobuf\Internal\Message */ public function getNamePart() { - return $this->name_part; + return isset($this->name_part) ? $this->name_part : ''; + } + + public function hasNamePart() + { + return isset($this->name_part); + } + + public function clearNamePart() + { + unset($this->name_part); } /** @@ -65,23 +73,27 @@ class NamePart extends \Google\Protobuf\Internal\Message { GPBUtil::checkString($var, True); $this->name_part = $var; - $this->has_name_part = true; return $this; } - public function hasNamePart() - { - return $this->has_name_part; - } - /** * Generated from protobuf field required bool is_extension = 2; * @return bool */ public function getIsExtension() { - return $this->is_extension; + return isset($this->is_extension) ? $this->is_extension : false; + } + + public function hasIsExtension() + { + return isset($this->is_extension); + } + + public function clearIsExtension() + { + unset($this->is_extension); } /** @@ -93,16 +105,10 @@ class NamePart extends \Google\Protobuf\Internal\Message { GPBUtil::checkBool($var); $this->is_extension = $var; - $this->has_is_extension = true; return $this; } - public function hasIsExtension() - { - return $this->has_is_extension; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Mixin.php b/php/src/Google/Protobuf/Mixin.php index a2ea59c757..cf6277eb70 100644 --- a/php/src/Google/Protobuf/Mixin.php +++ b/php/src/Google/Protobuf/Mixin.php @@ -46,7 +46,7 @@ use Google\Protobuf\Internal\GPBUtil; * The mixin construct implies that all methods in `AccessControl` are * also declared with same name and request/response types in * `Storage`. A documentation generator or annotation processor will - * see the effective `Storage.GetAcl` method after inherting + * see the effective `Storage.GetAcl` method after inheriting * documentation and annotations as follows: * service Storage { * // Get the underlying ACL object. diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php index a72cbb2edb..61569f8a36 100644 --- a/php/src/Google/Protobuf/NullValue.php +++ b/php/src/Google/Protobuf/NullValue.php @@ -35,6 +35,7 @@ class NullValue return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php index d9736634e3..92b4e279da 100644 --- a/php/src/Google/Protobuf/OneofDescriptor.php +++ b/php/src/Google/Protobuf/OneofDescriptor.php @@ -72,4 +72,9 @@ class OneofDescriptor { return count($this->internal_desc->getFields()); } + + public function isSynthetic() + { + return $this->internal_desc->isSynthetic(); + } } diff --git a/php/src/Google/Protobuf/Value.php b/php/src/Google/Protobuf/Value.php index 5c1e864c3d..20db3cc3e3 100644 --- a/php/src/Google/Protobuf/Value.php +++ b/php/src/Google/Protobuf/Value.php @@ -57,6 +57,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(1); } + public function hasNullValue() + { + return $this->hasOneof(1); + } + /** * Represents a null value. * @@ -83,6 +88,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(2); } + public function hasNumberValue() + { + return $this->hasOneof(2); + } + /** * Represents a double value. * @@ -109,6 +119,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(3); } + public function hasStringValue() + { + return $this->hasOneof(3); + } + /** * Represents a string value. * @@ -135,6 +150,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(4); } + public function hasBoolValue() + { + return $this->hasOneof(4); + } + /** * Represents a boolean value. * @@ -161,6 +181,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(5); } + public function hasStructValue() + { + return $this->hasOneof(5); + } + /** * Represents a structured value. * @@ -187,6 +212,11 @@ class Value extends \Google\Protobuf\Internal\Message return $this->readOneof(6); } + public function hasListValue() + { + return $this->hasOneof(6); + } + /** * Represents a repeated `Value`. * diff --git a/php/tests/array_test.php b/php/tests/ArrayTest.php similarity index 99% rename from php/tests/array_test.php rename to php/tests/ArrayTest.php index b251404083..2cb4b3910d 100644 --- a/php/tests/array_test.php +++ b/php/tests/ArrayTest.php @@ -7,7 +7,7 @@ use Google\Protobuf\Internal\GPBType; use Foo\TestMessage; use Foo\TestMessage\Sub; -class RepeatedFieldTest extends \PHPUnit\Framework\TestCase +class ArrayTest extends \PHPUnit\Framework\TestCase { ######################################################### diff --git a/php/tests/descriptors_test.php b/php/tests/DescriptorsTest.php similarity index 99% rename from php/tests/descriptors_test.php rename to php/tests/DescriptorsTest.php index 60a6292cb6..b2c5e0144d 100644 --- a/php/tests/descriptors_test.php +++ b/php/tests/DescriptorsTest.php @@ -108,7 +108,7 @@ class DescriptorsTest extends TestBase public function testEnumDescriptor() { - // WARNINIG - we need to do this so that TestDescriptorsEnum is registered!!? + // WARNING - we need to do this so that TestDescriptorsEnum is registered!!? new TestDescriptorsMessage(); $pool = DescriptorPool::getGeneratedPool(); diff --git a/php/tests/encode_decode_test.php b/php/tests/EncodeDecodeTest.php similarity index 97% rename from php/tests/encode_decode_test.php rename to php/tests/EncodeDecodeTest.php index 5442f504d5..cea1e6a47f 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/EncodeDecodeTest.php @@ -326,6 +326,42 @@ class EncodeDecodeTest extends TestBase } + public function testEncodeDecodeOptional() + { + $m = new TestMessage(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $data = $m->serializeToString(); + $this->assertSame("", $data); + + $m->setTrueOptionalInt32(0); + $this->assertTrue($m->hasTrueOptionalInt32()); + $data = $m->serializeToString(); + $this->assertNotSame("", $data); + + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m2->hasTrueOptionalInt32()); + $this->assertSame(0, $m2->getTrueOptionalInt32()); + } + + public function testJsonEncodeDecodeOptional() + { + $m = new TestMessage(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $data = $m->serializeToJsonString(); + $this->assertSame("{}", $data); + + $m->setTrueOptionalInt32(0); + $this->assertTrue($m->hasTrueOptionalInt32()); + $data = $m->serializeToJsonString(); + $this->assertNotSame("{}", $data); + + $m2 = new TestMessage(); + $m2->mergeFromJsonString($data); + $this->assertTrue($m2->hasTrueOptionalInt32()); + $this->assertSame(0, $m2->getTrueOptionalInt32()); + } + public function testJsonEncodeDecodeOneof() { $m = new TestMessage(); diff --git a/php/tests/generated_class_test.php b/php/tests/GeneratedClassTest.php similarity index 98% rename from php/tests/generated_class_test.php rename to php/tests/GeneratedClassTest.php index 053697d2ec..f49c4e970c 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/GeneratedClassTest.php @@ -71,6 +71,28 @@ class GeneratedClassTest extends TestBase $this->assertSame(MIN_INT32, $m->getOptionalInt32()); } + ######################################################### + # Test optional int32 field. + ######################################################### + + public function testOptionalInt32Field() + { + $m = new TestMessage(); + + $this->assertFalse($m->hasTrueOptionalInt32()); + $this->assertSame(0, $m->getTrueOptionalInt32()); + + // Set integer. + $m->setTrueOptionalInt32(MAX_INT32); + $this->assertTrue($m->hasTrueOptionalInt32()); + $this->assertSame(MAX_INT32, $m->getTrueOptionalInt32()); + + // Clear integer. + $m->clearTrueOptionalInt32(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $this->assertSame(0, $m->getTrueOptionalInt32()); + } + ######################################################### # Test uint32 field. ######################################################### diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/GeneratedPhpdocTest.php similarity index 100% rename from php/tests/generated_phpdoc_test.php rename to php/tests/GeneratedPhpdocTest.php diff --git a/php/tests/generated_service_test.php b/php/tests/GeneratedServiceTest.php similarity index 100% rename from php/tests/generated_service_test.php rename to php/tests/GeneratedServiceTest.php diff --git a/php/tests/map_field_test.php b/php/tests/MapFieldTest.php similarity index 100% rename from php/tests/map_field_test.php rename to php/tests/MapFieldTest.php diff --git a/php/tests/php_implementation_test.php b/php/tests/PhpImplementationTest.php similarity index 99% rename from php/tests/php_implementation_test.php rename to php/tests/PhpImplementationTest.php index db3c361caf..f9fc1fd5ea 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/PhpImplementationTest.php @@ -515,7 +515,7 @@ class ImplementationTest extends TestBase { $m = new TestMessage(); TestUtil::setTestMessage($m); - $this->assertSame(518, $m->byteSize()); + $this->assertSame(504, $m->byteSize()); } public function testPackedByteSize() diff --git a/php/tests/well_known_test.php b/php/tests/WellKnownTest.php similarity index 100% rename from php/tests/well_known_test.php rename to php/tests/WellKnownTest.php diff --git a/php/tests/wrapper_type_setters_test.php b/php/tests/WrapperTypeSettersTest.php similarity index 100% rename from php/tests/wrapper_type_setters_test.php rename to php/tests/WrapperTypeSettersTest.php diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh index ddf05e85c7..7e44cce06b 100755 --- a/php/tests/compatibility_test.sh +++ b/php/tests/compatibility_test.sh @@ -100,11 +100,18 @@ cd protobuf/php composer install # Remove implementation detail tests. -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) +# TODO(teboring): Temporarily disable encode_decode_test.php. In 3.13.0-rc1, +# repeated primitive field encoding is changed to packed, which is a bug fix. +# However, this fails the compatibility test which hard coded old encoding. +# Will re-enable the test after making a release. After the version bump, the +# compatibility test will use the updated test code. +tests=( array_test.php generated_class_test.php map_field_test.php well_known_test.php ) sed -i.bak '/php_implementation_test.php/d' phpunit.xml sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml +sed -i.bak '/encode_decode_test.php/d' phpunit.xml sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh sed -i.bak 's/generated_service_test.php//g' tests/test.sh +sed -i.bak 's/encode_decode_test.php//g' tests/test.sh sed -i.bak '/memory_leak_test.php/d' tests/test.sh sed -i.bak '/^ public function testTimestamp()$/,/^ }$/d' tests/well_known_test.php sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php diff --git a/php/tests/compile_extension.sh b/php/tests/compile_extension.sh index 5834249e39..d6dcabcbbb 100755 --- a/php/tests/compile_extension.sh +++ b/php/tests/compile_extension.sh @@ -4,17 +4,17 @@ set -ex cd $(dirname $0) +pushd ../ext/google/protobuf +phpize --clean +rm -f configure.in configure.ac +php make-preload.php +phpize if [ "$1" = "--release" ]; then - CFLAGS="-Wall" + ./configure --with-php-config=$(which php-config) else # To get debugging symbols in PHP itself, build PHP with: # $ ./configure --enable-debug CFLAGS='-g -O0' - CFLAGS="-g -O0 -Wall" + ./configure --with-php-config=$(which php-config) CFLAGS="-g -O0 -Wall" fi - -pushd ../ext/google/protobuf -phpize --clean -rm -f configure.in configure.ac -php make-preload.php -phpize && ./configure --with-php-config=$(which php-config) CFLAGS="$CFLAGS" && make +make popd diff --git a/php/tests/generate_protos.sh b/php/tests/generate_protos.sh index 0c2a5550aa..e83c3c1c06 100755 --- a/php/tests/generate_protos.sh +++ b/php/tests/generate_protos.sh @@ -7,10 +7,10 @@ cd `dirname $0` rm -rf generated mkdir -p generated -find proto -type f -name "*.proto"| xargs ../../src/protoc --php_out=generated -I../../src -I. +find proto -type f -name "*.proto"| xargs ../../src/protoc --experimental_allow_proto3_optional --php_out=generated -I../../src -I. if [ "$1" = "--aggregate_metadata" ]; then # Overwrite some of the files to use aggregation. AGGREGATED_FILES="proto/test.proto proto/test_include.proto proto/test_import_descriptor_proto.proto" - ../../src/protoc --php_out=aggregate_metadata=foo#bar:generated -I../../src -I. $AGGREGATED_FILES + ../../src/protoc --experimental_allow_proto3_optional --php_out=aggregate_metadata=foo#bar:generated -I../../src -I. $AGGREGATED_FILES fi diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index 95057090f9..368b19ec4d 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -34,6 +34,27 @@ message TestMessage { bar.TestInclude optional_included_message = 18; TestMessage recursive = 19; + // True optional + optional int32 true_optional_int32 = 201; + optional int64 true_optional_int64 = 202; + optional uint32 true_optional_uint32 = 203; + optional uint64 true_optional_uint64 = 204; + optional sint32 true_optional_sint32 = 205; + optional sint64 true_optional_sint64 = 206; + optional fixed32 true_optional_fixed32 = 207; + optional fixed64 true_optional_fixed64 = 208; + optional sfixed32 true_optional_sfixed32 = 209; + optional sfixed64 true_optional_sfixed64 = 210; + optional float true_optional_float = 211; + optional double true_optional_double = 212; + optional bool true_optional_bool = 213; + optional string true_optional_string = 214; + optional bytes true_optional_bytes = 215; + + optional TestEnum true_optional_enum = 216; + optional Sub true_optional_message = 217; + optional bar.TestInclude true_optional_included_message = 218; + // Repeated repeated int32 repeated_int32 = 31; repeated int64 repeated_int64 = 32; diff --git a/php/tests/test.sh b/php/tests/test.sh index b10b57fd19..91ea56ec8f 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -18,6 +18,9 @@ case "$PHP_VERSION" in 7.3.*|7.4.*) PHPUNIT=phpunit-8.phar ;; + 8.0.*) + PHPUNIT=phpunit-9.phar + ;; *) echo "ERROR: Unsupported PHP version $PHP_VERSION" exit 1 @@ -26,7 +29,7 @@ esac [ -f $PHPUNIT ] || wget https://phar.phpunit.de/$PHPUNIT -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php descriptors_test.php wrapper_type_setters_test.php) +tests=( ArrayTest.php EncodeDecodeTest.php GeneratedClassTest.php MapFieldTest.php WellKnownTest.php DescriptorsTest.php WrapperTypeSettersTest.php) for t in "${tests[@]}" do @@ -51,11 +54,11 @@ done export ZEND_DONT_UNLOAD_MODULES=1 export USE_ZEND_ALLOC=0 -valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php -valgrind --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +valgrind --suppressions=valgrind.supp --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +valgrind --suppressions=valgrind.supp --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php # TODO(teboring): Only for debug (phpunit has memory leak which blocks this beging used by -# regresssion test.) +# regression test.) # for t in "${tests[@]}" # do diff --git a/php/tests/test_util.php b/php/tests/test_util.php index 2c5b59541c..c47bf586a9 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -338,38 +338,24 @@ class TestUtil "800101" . "8A01020821" . - "F801D6FFFFFFFFFFFFFFFF01" . - "F801CCFFFFFFFFFFFFFFFF01" . - "8002D5FFFFFFFFFFFFFFFF01" . - "8002CBFFFFFFFFFFFFFFFF01" . - "88022A" . - "880234" . - "90022B" . - "900235" . - "980257" . - "98026B" . - "A00259" . - "A0026D" . - "AD022E000000" . - "AD0238000000" . - "B1022F00000000000000" . - "B1023900000000000000" . - "BD02D2FFFFFF" . - "BD02C8FFFFFF" . - "C102D1FFFFFFFFFFFFFF" . - "C102C7FFFFFFFFFFFFFF" . - "CD020000C03F" . - "CD0200002040" . - "D1029A9999999999F93F" . - "D102CDCCCCCCCCCC0440" . - "D80201" . - "D80200" . + "FA0114D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" . + "820214D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" . + "8A02022A34" . + "9202022B35" . + "9A0202576B" . + "A20202596D" . + "AA02082E00000038000000" . + "B202102F000000000000003900000000000000" . + "BA0208D2FFFFFFC8FFFFFF" . + "C20210D1FFFFFFFFFFFFFFC7FFFFFFFFFFFFFF" . + "CA02080000C03F00002040" . + "D202109A9999999999F93FCDCCCCCCCCCC0440" . + "DA02020100" . "E2020161" . "E2020163" . "EA020462626262" . "EA020464646464" . - "F00200" . - "F00201" . + "F202020001" . "FA02020822" . "FA02020823" . diff --git a/php/tests/valgrind.supp b/php/tests/valgrind.supp new file mode 100644 index 0000000000..e83b0a3dfa --- /dev/null +++ b/php/tests/valgrind.supp @@ -0,0 +1,12 @@ +{ + PHP_Equal_Val + Memcheck:Cond + fun:zend_string_equal_val +} + +{ + PHP_ScanDir_Tail + Memcheck:Cond + obj:/usr/bin/php7.3 + fun:__scandir64_tail +} diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 6d750c5b67..27315e83f4 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.12.3 + 3.13.0 pom Protobuf Compiler diff --git a/python/README.md b/python/README.md index a987c2dac8..cb8b7e9892 100644 --- a/python/README.md +++ b/python/README.md @@ -22,7 +22,7 @@ package. Development Warning =================== -The pure python performance is slow. For better preformance please +The pure python performance is slow. For better performance please use python c++ implementation. Installation diff --git a/python/google/protobuf/internal/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py index c8e10137b9..9ae0066584 100644 --- a/python/google/protobuf/internal/enum_type_wrapper.py +++ b/python/google/protobuf/internal/enum_type_wrapper.py @@ -108,7 +108,9 @@ class EnumTypeWrapper(object): def __getattr__(self, name): """Returns the value corresponding to the given enum name.""" try: - return self._enum_type.values_by_name[name].number + return super( + EnumTypeWrapper, + self).__getattribute__('_enum_type').values_by_name[name].number except KeyError: pass # fall out to break exception chaining raise AttributeError('Enum {} has no value defined for name {!r}'.format( diff --git a/python/release.sh b/python/release.sh index c915e124d8..6db87f0bb2 100755 --- a/python/release.sh +++ b/python/release.sh @@ -11,7 +11,10 @@ function run_install_test() { local PYTHON=$2 local PYPI=$3 - virtualenv --no-site-packages -p `which $PYTHON` test-venv + # Setuptools 45.0 removed support for Python 2, so to test with Python 2 we + # pass --no-setuptools here and then install an older setuptools version + # below. + virtualenv -p `which $PYTHON` --no-setuptools test-venv # Intentionally put a broken protoc in the path to make sure installation # doesn't require protoc installed. @@ -19,6 +22,7 @@ function run_install_test() { chmod +x test-venv/bin/protoc source test-venv/bin/activate + pip install "setuptools<45" pip install -i ${PYPI} protobuf==${VERSION} --no-cache-dir deactivate rm -fr test-venv diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h index bdc20ebeef..b7da76fa00 100644 --- a/ruby/ext/google/protobuf_c/upb.h +++ b/ruby/ext/google/protobuf_c/upb.h @@ -200,7 +200,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); ** store pointers or integers of at least 32 bits (upb isn't really useful on ** systems where sizeof(void*) < 4). ** -** The table must be homogenous (all values of the same type). In debug +** The table must be homogeneous (all values of the same type). In debug ** mode, we check this on insert and lookup. */ @@ -6057,7 +6057,7 @@ typedef struct { typedef struct { /* Space optimization note: we store two pointers here that the JIT * doesn't need at all; the upb_handlers* inside the sink and - * the dispatch table pointer. We can optimze so that the JIT uses + * the dispatch table pointer. We can optimize so that the JIT uses * smaller stack frames than the interpreter. The only thing we need * to guarantee is that the fallback routines can find end_ofs. */ upb_sink sink; diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 2160d520ab..21528fe4c3 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.12.3" + s.version = "3.13.0" git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" diff --git a/src/Makefile.am b/src/Makefile.am index 714fe71170..ca460aa73f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,6 +208,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/implicit_weak_message.cc \ + google/protobuf/map.cc \ google/protobuf/message_lite.cc \ google/protobuf/parse_context.cc \ google/protobuf/repeated_field.cc \ diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc index a9876fc4ed..ebe9ba7e0a 100644 --- a/src/google/protobuf/any.cc +++ b/src/google/protobuf/any.cc @@ -47,18 +47,20 @@ void AnyMetadata::PackFrom(const Message& message) { void AnyMetadata::PackFrom(const Message& message, StringPiece type_url_prefix) { - type_url_->SetNoArena( + type_url_->Set( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), - GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix)); - message.SerializeToString(value_->MutableNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())); + GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), + nullptr); + message.SerializeToString(value_->Mutable( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + nullptr)); } bool AnyMetadata::UnpackTo(Message* message) const { if (!InternalIs(message->GetDescriptor()->full_name())) { return false; } - return message->ParseFromString(value_->GetNoArena()); + return message->ParseFromString(value_->Get()); } bool GetAnyFieldDescriptors(const Message& message, diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 7eed87c5eb..3170748106 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_Any_google_2fprotobuf_2fany_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Any(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Any::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto = @@ -82,8 +81,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Any::InitAsDefaultInstance() { -} bool Any::GetAnyFieldDescriptors( const ::PROTOBUF_NAMESPACE_ID::Message& message, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 90cd342080..1c50d6eb72 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL : } static const Any& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Any* internal_default_instance() { return reinterpret_cast( &_Any_default_instance_); diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index 3badb411f1..206b01fbd1 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -59,10 +59,10 @@ AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value) void AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { - type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(), - GetTypeUrl(type_name, type_url_prefix)); - message.SerializeToString(value_->MutableNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited())); + type_url_->Set(&::google::protobuf::internal::GetEmptyString(), + GetTypeUrl(type_name, type_url_prefix), nullptr); + message.SerializeToString(value_->Mutable( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), nullptr)); } bool AnyMetadata::InternalUnpackTo(StringPiece type_name, @@ -70,31 +70,11 @@ bool AnyMetadata::InternalUnpackTo(StringPiece type_name, if (!InternalIs(type_name)) { return false; } - return message->ParseFromString(value_->GetNoArena()); + return message->ParseFromString(value_->Get()); } -namespace { - -// The type URL could be stored in either an ArenaStringPtr or a -// StringPieceField, so we provide these helpers to get a string_view from -// either type. We use a template function as a way to avoid depending on -// StringPieceField. - -template -StringPiece Get(const T* ptr) { - return ptr->Get(); -} - -template <> -// NOLINTNEXTLINE: clang-diagnostic-unused-function -StringPiece Get(const ArenaStringPtr* ptr) { - return ptr->GetNoArena(); -} - -} // namespace - bool AnyMetadata::InternalIs(StringPiece type_name) const { - StringPiece type_url = Get(type_url_); + StringPiece type_url = type_url_->Get(); return type_url.size() >= type_name.size() + 1 && type_url[type_url.size() - type_name.size() - 1] == '/' && HasSuffixString(type_url, type_name); diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 6ae678a120..f8e20a11d9 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -40,7 +40,6 @@ static void InitDefaultsscc_info_Api_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Api(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Api::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<4> scc_info_Api_google_2fprotobuf_2fapi_2eproto = @@ -58,7 +57,6 @@ static void InitDefaultsscc_info_Method_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Method(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Method::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto = @@ -73,7 +71,6 @@ static void InitDefaultsscc_info_Mixin_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Mixin(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Mixin::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto = @@ -172,10 +169,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Api::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Api::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg); @@ -601,8 +594,6 @@ void Api::InternalSwap(Api* other) { // =================================================================== -void Method::InitAsDefaultInstance() { -} class Method::_Internal { public: }; @@ -1002,8 +993,6 @@ void Method::InternalSwap(Method* other) { // =================================================================== -void Mixin::InitAsDefaultInstance() { -} class Mixin::_Internal { public: }; diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index a3c61a4e3b..64f90ee0e6 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -112,7 +112,6 @@ class PROTOBUF_EXPORT Api PROTOBUF_FINAL : } static const Api& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Api* internal_default_instance() { return reinterpret_cast( &_Api_default_instance_); @@ -365,7 +364,6 @@ class PROTOBUF_EXPORT Method PROTOBUF_FINAL : } static const Method& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Method* internal_default_instance() { return reinterpret_cast( &_Method_default_instance_); @@ -598,7 +596,6 @@ class PROTOBUF_EXPORT Mixin PROTOBUF_FINAL : } static const Mixin& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Mixin* internal_default_instance() { return reinterpret_cast( &_Mixin_default_instance_); @@ -941,8 +938,8 @@ inline bool Api::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 7362b62950..13e11b51aa 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -166,27 +166,19 @@ void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) { PROTOBUF_NOINLINE void* ArenaImpl::AllocateAlignedFallback(size_t n) { - return GetSerialArena()->AllocateAligned(n); + return GetSerialArenaFallback(&thread_cache())->AllocateAligned(n); } PROTOBUF_NOINLINE void* ArenaImpl::AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*)) { - return GetSerialArena()->AllocateAlignedAndAddCleanup(n, cleanup); + return GetSerialArenaFallback( + &thread_cache())->AllocateAlignedAndAddCleanup(n, cleanup); } PROTOBUF_NOINLINE void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { - GetSerialArena()->AddCleanup(elem, cleanup); -} - -ArenaImpl::SerialArena* ArenaImpl::GetSerialArena() { - SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena; - } else { - return GetSerialArenaFallback(&thread_cache()); - } + GetSerialArenaFallback(&thread_cache())->AddCleanup(elem, cleanup); } PROTOBUF_NOINLINE diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index c9b4c54fcb..2f8d343fd3 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -329,7 +329,6 @@ class PROTOBUF_EXPORT ArenaImpl { Block* NewBlock(Block* last_block, size_t min_bytes); - SerialArena* GetSerialArena(); PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) { if (GetSerialArenaFromThreadCache(arena)) return true; diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 85784201c2..8919027a89 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -1166,7 +1166,6 @@ TEST(ArenaTest, MessageLiteOnArena) { } #endif // PROTOBUF_RTTI - // RepeatedField should support non-POD types, and invoke constructors and // destructors appropriately, because it's used this way by lots of other code // (even if this was not its original intent). diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 122f391e51..b87be8e39b 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -229,7 +229,6 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // Clears content, assuming that the current value is not the empty string // default. inline void ClearNonDefaultToEmpty() { ptr_->clear(); } - inline void ClearNonDefaultToEmptyNoArena() { ptr_->clear(); } // Clears content, but keeps allocated string if arena != NULL, to avoid the // overhead of heap operations. After this returns, the content (as seen by @@ -257,93 +256,13 @@ struct PROTOBUF_EXPORT ArenaStringPtr { ptr_ = const_cast< ::std::string*>(default_value); } - // The 'NoArena' variants of methods below assume arena == NULL and are - // optimized to provide very little overhead relative to a raw string pointer - // (while still being in-memory compatible with other code that assumes - // ArenaStringPtr). Note the invariant that a class instance that has only - // ever been mutated by NoArena methods must *only* be in the String state - // (i.e., tag bits are not used), *NEVER* ArenaString. This allows all - // tagged-pointer manipulations to be avoided. - inline void SetNoArena(const ::std::string* default_value, - const ::std::string& value) { - if (ptr_ == default_value) { - CreateInstanceNoArena(&value); - } else { - *ptr_ = value; - } - } - - void SetNoArena(const ::std::string* default_value, ::std::string&& value) { - if (IsDefault(default_value)) { - ptr_ = new ::std::string(std::move(value)); - } else { - *ptr_ = std::move(value); - } - } - - void AssignWithDefault(const ::std::string* default_value, - ArenaStringPtr value); - - inline const ::std::string& GetNoArena() const { return *ptr_; } - - inline ::std::string* MutableNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - CreateInstanceNoArena(default_value); - } - return ptr_; - } - - inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - return NULL; - } else { - return ReleaseNonDefaultNoArena(default_value); - } - } - - inline ::std::string* ReleaseNonDefaultNoArena( - const ::std::string* default_value) { - GOOGLE_DCHECK(!IsDefault(default_value)); - ::std::string* released = ptr_; - ptr_ = const_cast< ::std::string*>(default_value); - return released; - } - - inline void SetAllocatedNoArena(const ::std::string* default_value, - ::std::string* value) { - if (ptr_ != default_value) { - delete ptr_; - } - if (value != NULL) { - ptr_ = value; - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } - + // Destroy the string. Assumes `arena == nullptr`. inline void DestroyNoArena(const ::std::string* default_value) { if (ptr_ != default_value) { delete ptr_; } } - inline void ClearToEmptyNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - // Nothing: already equal to default (which is the empty string). - } else { - ptr_->clear(); - } - } - - inline void ClearToDefaultNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - // Nothing: already set to default. - } else { - // Reuse existing allocated instance. - *ptr_ = *default_value; - } - } - // Internal accessor used only at parse time to provide direct access to the // raw pointer from the shared parse routine (in the non-arenas case). The // parse routine does the string allocation in order to save code size in the @@ -379,22 +298,6 @@ struct PROTOBUF_EXPORT ArenaStringPtr { } }; -} // namespace internal -} // namespace protobuf - -namespace protobuf { -namespace internal { - -inline void ArenaStringPtr::AssignWithDefault( - const ::std::string* default_value, ArenaStringPtr value) { - const ::std::string* me = *UnsafeRawStringPointer(); - const ::std::string* other = *value.UnsafeRawStringPointer(); - // If the pointers are the same then do nothing. - if (me != other) { - SetNoArena(default_value, value.GetNoArena()); - } -} - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 693300df08..4d78bb1176 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -85,6 +85,12 @@ io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( return NULL; // make compiler happy } +io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& /*info*/) { + return OpenForInsert(filename, insertion_point); +} + void GeneratorContext::ListParsedFiles( std::vector* output) { GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles"; diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 21131d5a25..323f48e4a9 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -52,6 +52,7 @@ namespace io { class ZeroCopyOutputStream; } class FileDescriptor; +class GeneratedCodeInfo; namespace compiler { class AccessInfoMap; @@ -156,6 +157,15 @@ class PROTOC_EXPORT GeneratorContext { virtual io::ZeroCopyOutputStream* OpenForInsert( const std::string& filename, const std::string& insertion_point); + // Similar to OpenForInsert, but if `info` is non-empty, will open (or create) + // filename.pb.meta and insert info at the appropriate place with the + // necessary shifts. The default implementation ignores `info`. + // + // WARNING: This feature will be REMOVED in the near future. + virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); + // Returns a vector of FileDescriptors for all the files being compiled // in this run. Useful for languages, such as Go, that treat files // differently when compiled as a set rather than individually. diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 1ada897af1..859eb8b831 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -386,6 +386,9 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename); io::ZeroCopyOutputStream* OpenForInsert(const std::string& filename, const std::string& insertion_point); + io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); void ListParsedFiles(std::vector* output) { *output = parsed_files_; } @@ -393,7 +396,8 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { private: friend class MemoryOutputStream; - // map instead of unordered_map so that files are written in order (good when + // The files_ field maps from path keys to file content values. It's a map + // instead of an unordered_map so that files are written in order (good when // writing zips). std::map files_; const std::vector& parsed_files_; @@ -408,6 +412,10 @@ class CommandLineInterface::MemoryOutputStream MemoryOutputStream(GeneratorContextImpl* directory, const std::string& filename, const std::string& insertion_point); + MemoryOutputStream(GeneratorContextImpl* directory, + const std::string& filename, + const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); virtual ~MemoryOutputStream(); // implements ZeroCopyOutputStream --------------------------------- @@ -418,12 +426,23 @@ class CommandLineInterface::MemoryOutputStream int64_t ByteCount() const override { return inner_->ByteCount(); } private: - // Checks to see if "filename_.meta" exists in directory_; if so, fixes the + // Checks to see if "filename_.pb.meta" exists in directory_; if so, fixes the // offsets in that GeneratedCodeInfo record to reflect bytes inserted in // filename_ at original offset insertion_offset with length insertion_length. - // We assume that insertions will not occur within any given annotated span - // of text. - void UpdateMetadata(size_t insertion_offset, size_t insertion_length); + // Also adds in the data from info_to_insert_ with updated offsets governed by + // insertion_offset and indent_length. We assume that insertions will not + // occur within any given annotated span of text. insertion_content must end + // with an endline. + void UpdateMetadata(const std::string& insertion_content, + size_t insertion_offset, size_t insertion_length, + size_t indent_length); + + // Inserts info_to_insert_ into target_info, assuming that the relevant + // insertion was made at insertion_offset in file_content with the given + // indent_length. insertion_content must end with an endline. + void InsertShiftedInfo(const std::string& insertion_content, + size_t insertion_offset, size_t indent_length, + google::protobuf::GeneratedCodeInfo& target_info); // Where to insert the string when it's done. GeneratorContextImpl* directory_; @@ -438,6 +457,9 @@ class CommandLineInterface::MemoryOutputStream // StringOutputStream writing to data_. std::unique_ptr inner_; + + // The GeneratedCodeInfo to insert at the insertion point. + google::protobuf::GeneratedCodeInfo info_to_insert_; }; // ------------------------------------------------------------------- @@ -594,6 +616,13 @@ CommandLineInterface::GeneratorContextImpl::OpenForInsert( return new MemoryOutputStream(this, filename, insertion_point); } +io::ZeroCopyOutputStream* +CommandLineInterface::GeneratorContextImpl::OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info) { + return new MemoryOutputStream(this, filename, insertion_point, info); +} + // ------------------------------------------------------------------- CommandLineInterface::MemoryOutputStream::MemoryOutputStream( @@ -612,40 +641,114 @@ CommandLineInterface::MemoryOutputStream::MemoryOutputStream( insertion_point_(insertion_point), inner_(new io::StringOutputStream(&data_)) {} +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + GeneratorContextImpl* directory, const std::string& filename, + const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info) + : directory_(directory), + filename_(filename), + insertion_point_(insertion_point), + inner_(new io::StringOutputStream(&data_)), + info_to_insert_(info) {} + +void CommandLineInterface::MemoryOutputStream::InsertShiftedInfo( + const std::string& insertion_content, size_t insertion_offset, + size_t indent_length, google::protobuf::GeneratedCodeInfo& target_info) { + // Keep track of how much extra data was added for indents before the + // current annotation being inserted. `pos` and `source_annotation.begin()` + // are offsets in `insertion_content`. `insertion_offset` is updated so that + // it can be added to an annotation's `begin` field to reflect that + // annotation's updated location after `insertion_content` was inserted into + // the target file. + size_t pos = 0; + insertion_offset += indent_length; + for (const auto& source_annotation : info_to_insert_.annotation()) { + GeneratedCodeInfo::Annotation* annotation = target_info.add_annotation(); + int inner_indent = 0; + // insertion_content is guaranteed to end in an endline. This last endline + // has no effect on indentation. + for (; pos < source_annotation.end() && pos < insertion_content.size() - 1; + ++pos) { + if (insertion_content[pos] == '\n') { + if (pos >= source_annotation.begin()) { + // The beginning of the annotation is at insertion_offset, but the end + // can still move further in the target file. + inner_indent += indent_length; + } else { + insertion_offset += indent_length; + } + } + } + *annotation = source_annotation; + annotation->set_begin(annotation->begin() + insertion_offset); + insertion_offset += inner_indent; + annotation->set_end(annotation->end() + insertion_offset); + } +} + void CommandLineInterface::MemoryOutputStream::UpdateMetadata( - size_t insertion_offset, size_t insertion_length) { - auto it = directory_->files_.find(filename_ + ".meta"); - if (it == directory_->files_.end()) { + const std::string& insertion_content, size_t insertion_offset, + size_t insertion_length, size_t indent_length) { + auto it = directory_->files_.find(filename_ + ".pb.meta"); + if (it == directory_->files_.end() && info_to_insert_.annotation().empty()) { // No metadata was recorded for this file. return; } - std::string& encoded_data = it->second; GeneratedCodeInfo metadata; bool is_text_format = false; - if (!metadata.ParseFromString(encoded_data)) { - if (!TextFormat::ParseFromString(encoded_data, &metadata)) { - // The metadata is invalid. - std::cerr << filename_ - << ".meta: Could not parse metadata as wire or text format." - << std::endl; - return; - } - // Generators that use the public plugin interface emit text-format - // metadata (because in the public plugin protocol, file content must be - // UTF8-encoded strings). - is_text_format = true; - } - for (int i = 0; i < metadata.annotation_size(); ++i) { - GeneratedCodeInfo::Annotation* annotation = metadata.mutable_annotation(i); - if (annotation->begin() >= insertion_offset) { - annotation->set_begin(annotation->begin() + insertion_length); - annotation->set_end(annotation->end() + insertion_length); + std::string* encoded_data = nullptr; + if (it != directory_->files_.end()) { + encoded_data = &it->second; + // Try to decode a GeneratedCodeInfo proto from the .pb.meta file. It may be + // in wire or text format. Keep the same format when the data is written out + // later. + if (!metadata.ParseFromString(*encoded_data)) { + if (!TextFormat::ParseFromString(*encoded_data, &metadata)) { + // The metadata is invalid. + std::cerr + << filename_ + << ".pb.meta: Could not parse metadata as wire or text format." + << std::endl; + return; + } + // Generators that use the public plugin interface emit text-format + // metadata (because in the public plugin protocol, file content must be + // UTF8-encoded strings). + is_text_format = true; } + } else { + // Create a new file to store the new metadata in info_to_insert_. + encoded_data = + &directory_->files_.insert({filename_ + ".pb.meta", ""}).first->second; + } + GeneratedCodeInfo new_metadata; + bool crossed_offset = false; + size_t to_add = 0; + for (const auto& source_annotation : metadata.annotation()) { + // The first time an annotation at or after the insertion point is found, + // insert the new metadata from info_to_insert_. Shift all annotations + // after the new metadata by the length of the text that was inserted + // (including any additional indent length). + if (source_annotation.begin() >= insertion_offset && !crossed_offset) { + crossed_offset = true; + InsertShiftedInfo(insertion_content, insertion_offset, indent_length, + new_metadata); + to_add += insertion_length; + } + GeneratedCodeInfo::Annotation* annotation = new_metadata.add_annotation(); + *annotation = source_annotation; + annotation->set_begin(annotation->begin() + to_add); + annotation->set_end(annotation->end() + to_add); + } + // If there were never any annotations at or after the insertion point, + // make sure to still insert the new metadata from info_to_insert_. + if (!crossed_offset) { + InsertShiftedInfo(insertion_content, insertion_offset, indent_length, + new_metadata); } if (is_text_format) { - TextFormat::PrintToString(metadata, &encoded_data); + TextFormat::PrintToString(new_metadata, encoded_data); } else { - metadata.SerializeToString(&encoded_data); + new_metadata.SerializeToString(encoded_data); } } @@ -728,7 +831,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { if (indent_.empty()) { // No indent. This makes things easier. target->insert(pos, data_); - UpdateMetadata(pos, data_.size()); + UpdateMetadata(data_, pos, data_.size(), 0); } else { // Calculate how much space we need. int indent_size = 0; @@ -738,7 +841,6 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make a hole for it. target->insert(pos, data_.size() + indent_size, '\0'); - UpdateMetadata(pos, data_.size() + indent_size); // Now copy in the data. std::string::size_type data_pos = 0; @@ -757,6 +859,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { target_ptr += line_length; data_pos += line_length; } + UpdateMetadata(data_, pos, data_.size() + indent_size, indent_.size()); GOOGLE_CHECK_EQ(target_ptr, ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size); @@ -1427,13 +1530,33 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( proto_path_.push_back(std::pair("", ".")); } - // Check some error cases. - bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); - if (decoding_raw && !input_files_.empty()) { - std::cerr << "When using --decode_raw, no input files should be given." + // Check error cases that span multiple flag values. + bool missing_proto_definitions; + switch (mode_) { + case MODE_COMPILE: + missing_proto_definitions = input_files_.empty(); + break; + case MODE_DECODE: + // Handle --decode_raw separately, since it requires that no proto + // definitions are specified. + if (codec_type_.empty()) { + if (!input_files_.empty() || !descriptor_set_in_names_.empty()) { + std::cerr + << "When using --decode_raw, no input files should be given." << std::endl; - return PARSE_ARGUMENT_FAIL; - } else if (!decoding_raw && input_files_.empty()) { + return PARSE_ARGUMENT_FAIL; + } + missing_proto_definitions = false; + break; // only for --decode_raw + } + // --decode (not raw) is handled the same way as the rest of the modes. + PROTOBUF_FALLTHROUGH_INTENDED; + case MODE_ENCODE: + case MODE_PRINT: + missing_proto_definitions = + input_files_.empty() && descriptor_set_in_names_.empty(); + } + if (missing_proto_definitions) { std::cerr << "Missing input file." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -2224,8 +2347,10 @@ bool CommandLineInterface::GeneratePluginOutput( // We reset current_output to NULL first so that the old file is closed // before the new one is opened. current_output.reset(); - current_output.reset(generator_context->OpenForInsert( - filename, output_file.insertion_point())); + current_output.reset( + generator_context->OpenForInsertWithGeneratedCodeInfo( + filename, output_file.insertion_point(), + output_file.generated_code_info())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. // We reset current_output to NULL first so that the old file is closed diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index e42ca26e76..5d91042845 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -1192,8 +1192,8 @@ TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) { Run("protocol_compiler " "--test_out=TestParameter:$tmpdir " "--plug_out=TestPluginParameter:$tmpdir " - "--test_out=insert=test_generator,test_plugin:$tmpdir " - "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--test_out=insert_endlines=test_generator,test_plugin:$tmpdir " + "--plug_out=insert_endlines=test_generator,test_plugin:$tmpdir " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); @@ -2564,20 +2564,22 @@ class EncodeDecodeTest : public testing::TestWithParam { enum Type { TEXT, BINARY }; enum ReturnCode { SUCCESS, ERROR }; - bool Run(const std::string& command) { + bool Run(const std::string& command, bool specify_proto_files = true) { std::vector args; args.push_back("protoc"); SplitStringUsing(command, " ", &args); - switch (GetParam()) { - case PROTO_PATH: - args.push_back("--proto_path=" + TestUtil::TestSourceDir()); - break; - case DESCRIPTOR_SET_IN: - args.push_back(StrCat("--descriptor_set_in=", - unittest_proto_descriptor_set_filename_)); - break; - default: - ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + if (specify_proto_files) { + switch (GetParam()) { + case PROTO_PATH: + args.push_back("--proto_path=" + TestUtil::TestSourceDir()); + break; + case DESCRIPTOR_SET_IN: + args.push_back(StrCat("--descriptor_set_in=", + unittest_proto_descriptor_set_filename_)); + break; + default: + ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + } } std::unique_ptr argv(new const char*[args.size()]); @@ -2659,9 +2661,12 @@ TEST_P(EncodeDecodeTest, Encode) { RedirectStdinFromFile(TestUtil::GetTestDataPath( "net/proto2/internal/" "testdata/text_format_unittest_data_oneof_implemented.txt")); - EXPECT_TRUE( - Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") + - " --encode=protobuf_unittest.TestAllTypes")); + std::string args; + if (GetParam() != DESCRIPTOR_SET_IN) { + args.append( + TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto")); + } + EXPECT_TRUE(Run(args + " --encode=protobuf_unittest.TestAllTypes")); ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( "net/proto2/internal/testdata/golden_message_oneof_implemented")); ExpectStderrMatchesText(""); @@ -2697,7 +2702,7 @@ TEST_P(EncodeDecodeTest, DecodeRaw) { message.SerializeToString(&data); RedirectStdinFromText(data); - EXPECT_TRUE(Run("--decode_raw")); + EXPECT_TRUE(Run("--decode_raw", /*specify_proto_files=*/false)); ExpectStdoutMatchesText( "1: 123\n" "14: \"foo\"\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 7d69eb566b..c27b464f95 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -441,12 +441,11 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, " ::$proto_ns$::internal::ExplicitlyConstructed<$2$> _instance;\n", DefaultInstanceType(generator->descriptor_, options_), generator->classname_); - format.Indent(); - generator->GenerateExtraDefaultFields(printer); - format.Outdent(); format("} $1$;\n", DefaultInstanceName(generator->descriptor_, options_)); + if (options_.lite_implicit_weak_fields) { - format("$1$DefaultTypeInternal* $2$ = &$3$;\n", generator->classname_, + format("$1$* $2$ = &$3$;\n", + DefaultInstanceType(generator->descriptor_, options_), DefaultInstancePtr(generator->descriptor_, options_), DefaultInstanceName(generator->descriptor_, options_)); } @@ -942,8 +941,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { continue; } - // TODO(gerbens) This requires this function to be friend. Remove - // the need for this. message_generators_[i]->GenerateFieldDefaultInstances(printer); format( "{\n" @@ -961,17 +958,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, } format("}\n"); } - - // TODO(gerbens) make default instances be the same as normal instances. - // Default instances differ from normal instances because they have cross - // linked message fields. - for (int i = 0; i < message_generators_.size(); i++) { - if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { - continue; - } - format("$1$::InitAsDefaultInstance();\n", - QualifiedClassName(message_generators_[i]->descriptor_, options_)); - } format.Outdent(); format("}\n\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 976823afa8..2a338ae59f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -1388,7 +1388,7 @@ class ParseLoopGenerator { std::vector ordered_fields; for (auto field : FieldRange(descriptor)) { - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { ordered_fields.push_back(field); } } @@ -1615,9 +1615,13 @@ class ParseLoopGenerator { } } else if (IsWeak(field, options_)) { format_( - "ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($1$," - " _$classname$_default_instance_.$2$_), ptr);\n", - field->number(), FieldName(field)); + "{\n" + " auto* default_ = &reinterpret_cast($1$);\n" + " ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($2$," + " default_), ptr);\n" + "}\n", + QualifiedDefaultInstanceName(field->message_type(), options_), + field->number()); } else { format_("ptr = ctx->ParseMessage(_internal_$1$_$2$(), ptr);\n", field->is_repeated() ? "add" : "mutable", FieldName(field)); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 988e6092c1..4ee19b8b15 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -347,12 +347,16 @@ inline bool IsLazy(const FieldDescriptor* field, const Options& options) { !options.opensource_runtime; } -// Returns true if "field" is used. -inline bool IsFieldUsed(const FieldDescriptor* /*field*/, - const Options& /*options*/) { +inline bool IsFieldUsed(const FieldDescriptor* field, const Options& options) { return true; } +// Returns true if "field" is stripped. +inline bool IsFieldStripped(const FieldDescriptor* /*field*/, + const Options& /*options*/) { + return false; +} + // Does the file contain any definitions that need extension_set.h? bool HasExtensionsOrExtendableMessage(const FileDescriptor* file); @@ -450,27 +454,11 @@ inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; } -inline bool SupportsArenas(const FileDescriptor* file) { - return file->options().cc_enable_arenas(); -} - -inline bool SupportsArenas(const Descriptor* desc) { - return SupportsArenas(desc->file()); -} - -inline bool SupportsArenas(const FieldDescriptor* field) { - return SupportsArenas(field->file()); -} - inline bool IsCrossFileMessage(const FieldDescriptor* field) { return field->type() == FieldDescriptor::TYPE_MESSAGE && field->message_type()->file() != field->file(); } -inline std::string MessageCreateFunction(const Descriptor* d) { - return SupportsArenas(d) ? "CreateMessage" : "Create"; -} - inline std::string MakeDefaultName(const FieldDescriptor* field) { return "_i_give_permission_to_break_this_code_default_" + FieldName(field) + "_"; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 7c7461fa6f..19bf4252e5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -316,6 +316,17 @@ bool ShouldMarkNewAsFinal(const Descriptor* descriptor, options.opensource_runtime; } +// Returns true to make the message serialize in order, decided by the following +// factors in the order of precedence. +// --options().message_set_wire_format() == true +// --the message is in the allowlist (true) +// --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false) +// --a ranage of message names that are allowed to stay in order (true) +bool ShouldSerializeInOrder(const Descriptor* descriptor, + const Options& options) { + return true; +} + bool TableDrivenParsingEnabled(const Descriptor* descriptor, const Options& options) { if (!options.table_driven_parsing) { @@ -584,7 +595,7 @@ MessageGenerator::MessageGenerator( // Compute optimized field order to be used for layout and initialization // purposes. for (auto field : FieldRange(descriptor_)) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { continue; } @@ -673,7 +684,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { optimized_order_.end()); for (auto field : FieldRange(descriptor_)) { if (!field->real_containing_oneof() && !field->options().weak() && - IsFieldUsed(field, options_)) { + !IsFieldStripped(field, options_)) { continue; } ordered_fields.push_back(field); @@ -702,8 +713,8 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { if (field->is_repeated()) { format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field, - IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}"); - if (IsFieldUsed(field, options_)) { + !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); + if (!IsFieldStripped(field, options_)) { format( "private:\n" "int ${1$_internal_$name$_size$}$() const;\n" @@ -712,15 +723,15 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { } } else if (HasHasMethod(field)) { format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field, - IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}"); - if (IsFieldUsed(field, options_)) { + !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); + if (!IsFieldStripped(field, options_)) { format( "private:\n" "bool _internal_has_$name$() const;\n" "public:\n"); } } else if (HasPrivateHasMethod(field)) { - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { format( "private:\n" "bool ${1$_internal_has_$name$$}$() const;\n" @@ -729,7 +740,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { } } format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field, - IsFieldUsed(field, options_) ? ";" : "{__builtin_trap();}"); + !IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}"); // Generate type-specific accessor declarations. field_generators_.get(field).GenerateAccessorDeclarations(printer); @@ -764,7 +775,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { void MessageGenerator::GenerateSingularFieldHasBits( const FieldDescriptor* field, Formatter format) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { format( "inline bool $classname$::has_$name$() const { " "__builtin_trap(); }\n"); @@ -845,7 +856,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, const Formatter& format) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { if (HasHasMethod(field)) { format( "inline bool $classname$::has_$name$() const { " @@ -890,7 +901,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, bool is_inline, Formatter format) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { format("void $classname$::clear_$name$() { __builtin_trap(); }\n"); return; } @@ -936,7 +947,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { for (auto field : FieldRange(descriptor_)) { PrintFieldComment(format, field); - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { continue; } @@ -948,7 +959,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { format( "inline int $classname$::$name$_size() const { " "__builtin_trap(); }\n"); @@ -982,7 +993,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { } // Generate type-specific accessors. - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); } @@ -1105,13 +1116,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format(" public:\n"); format.Indent(); - if (SupportsArenas(descriptor_)) { - format("inline $classname$() : $classname$(nullptr) {}\n"); - } else { - format("$classname$();\n"); - } - format( + "inline $classname$() : $classname$(nullptr) {}\n" "virtual ~$classname$();\n" "\n" "$classname$(const $classname$& from);\n" @@ -1207,7 +1213,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // TODO(gerbens) make this private, while still granting other protos access. format( - "static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY\n" "static inline const $classname$* internal_default_instance() {\n" " return reinterpret_cast(\n" " &_$classname$_default_instance_);\n" @@ -1290,31 +1295,21 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format( "friend void swap($classname$& a, $classname$& b) {\n" " a.Swap(&b);\n" + "}\n" + "inline void Swap($classname$* other) {\n" + " if (other == this) return;\n" + " if (GetArena() == other->GetArena()) {\n" + " InternalSwap(other);\n" + " } else {\n" + " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" + " }\n" + "}\n" + "void UnsafeArenaSwap($classname$* other) {\n" + " if (other == this) return;\n" + " $DCHK$(GetArena() == other->GetArena());\n" + " InternalSwap(other);\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "inline void Swap($classname$* other) {\n" - " if (other == this) return;\n" - " if (GetArena() == other->GetArena()) {\n" - " InternalSwap(other);\n" - " } else {\n" - " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" - " }\n" - "}\n" - "void UnsafeArenaSwap($classname$* other) {\n" - " if (other == this) return;\n" - " $DCHK$(GetArena() == other->GetArena());\n" - " InternalSwap(other);\n" - "}\n"); - } else { - format( - "inline void Swap($classname$* other) {\n" - " if (other == this) return;\n" - " InternalSwap(other);\n" - "}\n"); - } - format( "\n" "// implements Message ----------------------------------------------\n" @@ -1387,17 +1382,15 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece" : "::StringPiece"); - if (SupportsArenas(descriptor_)) { - format( - // TODO(gerbens) Make this private! Currently people are deriving from - // protos to give access to this constructor, breaking the invariants - // we rely on. - "protected:\n" - "explicit $classname$(::$proto_ns$::Arena* arena);\n" - "private:\n" - "static void ArenaDtor(void* object);\n" - "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); - } + format( + // TODO(gerbens) Make this private! Currently people are deriving from + // protos to give access to this constructor, breaking the invariants + // we rely on. + "protected:\n" + "explicit $classname$(::$proto_ns$::Arena* arena);\n" + "private:\n" + "static void ArenaDtor(void* object);\n" + "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); format( "public:\n" @@ -1520,13 +1513,11 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); } - if (SupportsArenas(descriptor_)) { - format( - "template friend class " - "::$proto_ns$::Arena::InternalHelper;\n" - "typedef void InternalArenaConstructable_;\n" - "typedef void DestructorSkippable_;\n"); - } + format( + "template friend class " + "::$proto_ns$::Arena::InternalHelper;\n" + "typedef void InternalArenaConstructable_;\n" + "typedef void DestructorSkippable_;\n"); if (!has_bit_indices_.empty()) { // _has_bits_ is frequently accessed, so to reduce code size and improve @@ -1558,14 +1549,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { camel_oneof_name); format.Indent(); for (auto field : FieldRange(oneof)) { - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GeneratePrivateMembers(printer); } } format.Outdent(); format("} $1$_;\n", oneof->name()); for (auto field : FieldRange(oneof)) { - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateStaticMembers(printer); } } @@ -1623,30 +1614,6 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { } } -void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) { - // Generate oneof default instance and weak field instances for reflection - // usage. - Formatter format(printer, variables_); - for (auto oneof : OneOfRange(descriptor_)) { - for (auto field : FieldRange(oneof)) { - if (!IsFieldUsed(field, options_)) { - continue; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && - EffectiveStringCType(field, options_) != FieldOptions::STRING)) { - format("const "); - } - field_generators_.get(field).GeneratePrivateMembers(printer); - } - } - for (auto field : FieldRange(descriptor_)) { - if (field->options().weak() && IsFieldUsed(field, options_)) { - format(" const ::$proto_ns$::Message* $1$_;\n", FieldName(field)); - } - } -} - bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, size_t aux_offset) { Formatter format(printer, variables_); @@ -1938,66 +1905,6 @@ void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { } } -void MessageGenerator::GenerateDefaultInstanceInitializer( - io::Printer* printer) { - Formatter format(printer, variables_); - - // The default instance needs all of its embedded message pointers - // cross-linked to other default instances. We can't do this initialization - // in the constructor because some other default instances may not have been - // constructed yet at that time. - // TODO(kenton): Maybe all message fields (even for non-default messages) - // should be initialized to point at default instances rather than NULL? - for (auto field : FieldRange(descriptor_)) { - if (!IsFieldUsed(field, options_)) { - continue; - } - Formatter::SaveState saver(&format); - - if (!field->is_repeated() && !IsLazy(field, options_) && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - (!field->real_containing_oneof() || - HasDescriptorMethods(descriptor_->file(), options_))) { - std::string name; - if (field->real_containing_oneof() || field->options().weak()) { - name = "_" + classname_ + "_default_instance_."; - } else { - name = - "_" + classname_ + "_default_instance_._instance.get_mutable()->"; - } - name += FieldName(field); - format.Set("name", name); - if (IsWeak(field, options_)) { - format( - "$package_ns$::$name$_ = reinterpret_cast(&$1$);\n" - "if ($package_ns$::$name$_ == nullptr) {\n" - " $package_ns$::$name$_ = " - "::$proto_ns$::Empty::internal_default_instance();\n" - "}\n", - QualifiedDefaultInstanceName(field->message_type(), - options_)); // 1 - continue; - } - if (IsImplicitWeakField(field, options_, scc_analyzer_)) { - format( - "$package_ns$::$name$_ = reinterpret_cast<$1$*>(\n" - " $2$);\n", - FieldMessageTypeName(field, options_), - QualifiedDefaultInstancePtr(field->message_type(), options_)); - } else { - format( - "$package_ns$::$name$_ = const_cast< $1$*>(\n" - " $1$::internal_default_instance());\n", - FieldMessageTypeName(field, options_)); - } - } else if (field->real_containing_oneof() && - HasDescriptorMethods(descriptor_->file(), options_)) { - field_generators_.get(field).GenerateConstructorCode(printer); - } - } -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { @@ -2023,14 +1930,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { return; } - // TODO(gerbens) Remove this function. With a little bit of cleanup and - // refactoring this is superfluous. - format("void $classname$::InitAsDefaultInstance() {\n"); - format.Indent(); - GenerateDefaultInstanceInitializer(printer); - format.Outdent(); - format("}\n"); - if (IsAnyMessage(descriptor_, options_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( @@ -2062,7 +1961,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } for (auto field : FieldRange(descriptor_)) { field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { continue; } if (HasHasbit(field)) { @@ -2088,14 +1987,14 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format.Outdent(); format("};\n\n"); for (auto field : FieldRange(descriptor_)) { - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); } } // Generate non-inline field definitions. for (auto field : FieldRange(descriptor_)) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { continue; } field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer); @@ -2400,13 +2299,16 @@ std::pair MessageGenerator::GenerateOffsets( descriptor_->real_oneof_decl_count(); size_t entries = offsets; for (auto field : FieldRange(descriptor_)) { - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { format("~0u, // stripped\n"); continue; } - if (field->real_containing_oneof() || field->options().weak()) { - format("offsetof($classtype$DefaultTypeInternal, $1$_)", - FieldName(field)); + // TODO(sbenza): We should not have an entry in the offset table for fields + // that do not use them. + if (field->options().weak() || field->real_containing_oneof()) { + // Mark the field to prevent unintentional access through reflection. + // Don't use the top bit because that is for unused fields. + format("::$proto_ns$::internal::kInvalidFieldOffsetTag"); } else { format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); } @@ -2416,7 +2318,11 @@ std::pair MessageGenerator::GenerateOffsets( format(" | $1$", tag); } - format(",\n"); + if (!IsFieldUsed(field, options_)) { + format(" | 0x80000000u, // unused\n"); + } else { + format(",\n"); + } } int count = 0; @@ -2470,9 +2376,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { format("void $classname$::SharedDtor() {\n"); format.Indent(); - if (SupportsArenas(descriptor_)) { - format("$DCHK$(GetArena() == nullptr);\n"); - } + format("$DCHK$(GetArena() == nullptr);\n"); // Write the destructors for each field except oneof members. // optimized_order_ does not contain oneof fields. for (auto field : optimized_order_) { @@ -2528,7 +2432,7 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { // and returns false for oneof fields. for (auto oneof : OneOfRange(descriptor_)) { for (auto field : FieldRange(oneof)) { - if (IsFieldUsed(field, options_) && + if (!IsFieldStripped(field, options_) && field_generators_.get(field).GenerateArenaDestructorCode(printer)) { need_registration = true; } @@ -2631,7 +2535,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { // Initialize member variables with arena constructor. for (auto field : optimized_order_) { - GOOGLE_DCHECK(IsFieldUsed(field, options_)); + GOOGLE_DCHECK(!IsFieldStripped(field, options_)); bool has_arena_constructor = field->is_repeated(); if (!field->real_containing_oneof() && (IsLazy(field, options_) || IsStringPiece(field, options_))) { @@ -2658,24 +2562,14 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { initializer_null += ", _weak_field_map_(nullptr)"; } - if (SupportsArenas(descriptor_)) { - format( - "$classname$::$classname$(::$proto_ns$::Arena* arena)\n" - " : $1$ {\n" - " SharedCtor();\n" - " RegisterArenaDtor(arena);\n" - " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" - "}\n", - initializer_with_arena); - } else { - format( - "$classname$::$classname$()\n" - " : $1$ {\n" - " SharedCtor();\n" - " // @@protoc_insertion_point(constructor:$full_name$)\n" - "}\n", - initializer_null); - } + format( + "$classname$::$classname$(::$proto_ns$::Arena* arena)\n" + " : $1$ {\n" + " SharedCtor();\n" + " RegisterArenaDtor(arena);\n" + " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" + "}\n", + initializer_with_arena); std::map vars; SetUnknkownFieldsVariable(descriptor_, options_, &vars); @@ -2747,7 +2641,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { for (auto field : FieldRange(oneof)) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateMergingCode(printer); } format("break;\n"); @@ -2786,9 +2680,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { GenerateSharedDestructorCode(printer); // Generate the arena-specific destructor code. - if (SupportsArenas(descriptor_)) { - GenerateArenaDestructorCode(printer); - } + GenerateArenaDestructorCode(printer); // Generate SetCachedSize. format( @@ -2811,9 +2703,8 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { "template<> " "PROTOBUF_NOINLINE " "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" - " return Arena::$1$Internal< $classtype$ >(arena);\n" - "}\n", - MessageCreateFunction(descriptor_)); + " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" + "}\n"); } void MessageGenerator::GenerateClear(io::Printer* printer) { @@ -3005,7 +2896,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); // We clear only allocated objects in oneofs - if (!IsStringOrMessage(field) || !IsFieldUsed(field, options_)) { + if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) { format("// No need to clear\n"); } else { field_generators_.get(field).GenerateClearingCode(printer); @@ -3294,7 +3185,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { for (auto field : FieldRange(oneof)) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateMergingCode(printer); } format("break;\n"); @@ -3514,8 +3405,26 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n"); + if (!ShouldSerializeInOrder(descriptor_, options_)) { + format.Outdent(); + format("#ifdef NDEBUG\n"); + format.Indent(); + } + GenerateSerializeWithCachedSizesBody(printer); + if (!ShouldSerializeInOrder(descriptor_, options_)) { + format.Outdent(); + format("#else // NDEBUG\n"); + format.Indent(); + + GenerateSerializeWithCachedSizesBodyShuffled(printer); + + format.Outdent(); + format("#endif // !NDEBUG\n"); + format.Indent(); + } + format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n"); format.Outdent(); @@ -3630,11 +3539,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( (i < descriptor_->field_count() && ordered_fields[i]->number() < sorted_extensions[j]->start)) { const FieldDescriptor* field = ordered_fields[i++]; - if (!IsFieldUsed(field, options_)) { + if (IsFieldStripped(field, options_)) { continue; } if (field->options().weak()) { - last_weak_field = field; + if (last_weak_field == nullptr || + last_weak_field->number() < field->number()) { + last_weak_field = field; + } PrintFieldComment(format, field); } else { if (last_weak_field != nullptr) { @@ -3677,6 +3589,115 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( format("}\n"); } +void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( + io::Printer* printer) { + Formatter format(printer, variables_); + + std::vector ordered_fields = + SortFieldsByNumber(descriptor_); + ordered_fields.erase( + std::remove_if(ordered_fields.begin(), ordered_fields.end(), + [this](const FieldDescriptor* f) { + return !IsFieldUsed(f, options_); + }), + ordered_fields.end()); + + std::vector sorted_extensions; + sorted_extensions.reserve(descriptor_->extension_range_count()); + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); + + int num_fields = ordered_fields.size() + sorted_extensions.size(); + constexpr int kLargePrime = 1000003; + GOOGLE_CHECK_LT(num_fields, kLargePrime) + << "Prime offset must be greater than the number of fields to ensure " + "those are coprime."; + + if (num_weak_fields_) { + format( + "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" + "_weak_field_map_);\n"); + } + + format( + "static const int kStart = GetInvariantPerBuild($1$UL) % $2$;\n" + "bool first_pass = true;\n" + "for (int i = kStart; i != kStart || first_pass; i = ((i + $3$) % $2$)) " + "{\n", + 0, + num_fields, kLargePrime); + + format.Indent(); + format("switch(i) {\n"); + format.Indent(); + + bool first_pass_set = false; + int index = 0; + for (const auto* f : ordered_fields) { + format("case $1$: {\n", index++); + format.Indent(); + + if (!first_pass_set) { + first_pass_set = true; + format("first_pass = false;\n"); + } + + GenerateSerializeOneField(printer, f, -1); + + format("break;\n"); + format.Outdent(); + format("}\n"); + } + + for (const auto* r : sorted_extensions) { + format("case $1$: {\n", index++); + format.Indent(); + + if (!first_pass_set) { + first_pass_set = true; + format("first_pass = false;\n"); + } + + GenerateSerializeOneExtensionRange(printer, r); + + format("break;\n"); + format.Outdent(); + format("}\n"); + } + + format( + "default: {\n" + " $DCHK$(false) << \"Unexpected index: \" << i;\n" + "}\n"); + format.Outdent(); + format("}\n"); + + format.Outdent(); + format("}\n"); + + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); + format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); + format.Indent(); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + format( + "target = " + "::$proto_ns$::internal::WireFormat::" + "InternalSerializeUnknownFieldsToArray(\n" + " $unknown_fields$, target, stream);\n"); + } else { + format( + "target = stream->WriteRaw($unknown_fields$.data(),\n" + " static_cast($unknown_fields$.size()), target);\n"); + } + format.Outdent(); + format("}\n"); +} + std::vector MessageGenerator::RequiredFieldsBitMask() const { const int array_size = HasBitsSize(); std::vector masks(array_size, 0); @@ -3898,7 +3919,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { PrintFieldComment(format, field); format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - if (IsFieldUsed(field, options_)) { + if (!IsFieldStripped(field, options_)) { field_generators_.get(field).GenerateByteSize(printer); } format("break;\n"); @@ -4026,7 +4047,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - if (IsFieldUsed(field, options_) && + if (!IsFieldStripped(field, options_) && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index a212ff416b..8917d1384d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,17 +82,9 @@ class MessageGenerator { // Source file stuff. - // Generate extra fields - void GenerateExtraDefaultFields(io::Printer* printer); - // Generates code that creates default instances for fields. void GenerateFieldDefaultInstances(io::Printer* printer); - // Generates code that initializes the message's default instance. This - // is separate from allocating because all default instances must be - // allocated before any can be initialized. - void GenerateDefaultInstanceInitializer(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); @@ -142,6 +134,7 @@ class MessageGenerator { void GenerateSerializeWithCachedSizes(io::Printer* printer); void GenerateSerializeWithCachedSizesToArray(io::Printer* printer); void GenerateSerializeWithCachedSizesBody(io::Printer* printer); + void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer); void GenerateByteSize(io::Printer* printer); void GenerateMergeFrom(io::Printer* printer); void GenerateClassSpecificMergeFrom(io::Printer* printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 38fcb52e6c..f1a5cef1de 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -67,8 +67,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, QualifiedDefaultInstancePtr(descriptor->message_type(), options); (*variables)["type_reference_function"] = implicit_weak ? (" ::" + (*variables)["proto_ns"] + - "::internal::StrongReference(" + - (*variables)["type_default_instance"] + ");\n") + "::internal::StrongReference(reinterpret_cast(\n" + + (*variables)["type_default_instance"] + "));\n") : ""; // NOTE: Escaped here to unblock proto1->proto2 migration. // TODO(liujisi): Extend this to apply for other conflicting methods. @@ -104,7 +105,7 @@ void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { void MessageFieldGenerator::GenerateAccessorDeclarations( io::Printer* printer) const { Formatter format(printer, variables_); - if (!IsFieldUsed(descriptor_, options_)) { + if (IsFieldStripped(descriptor_, options_)) { format( "$deprecated_attr$const $type$& ${1$$name$$}$() const { " "__builtin_trap(); }\n" @@ -113,17 +114,13 @@ void MessageFieldGenerator::GenerateAccessorDeclarations( "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { " "__builtin_trap(); }\n" "$deprecated_attr$void ${1$set_allocated_$name$$}$" - "($type$* $name$) { __builtin_trap(); }\n", + "($type$* $name$) { __builtin_trap(); }\n" + "$deprecated_attr$void " + "${1$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$) { __builtin_trap(); }\n" + "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { " + "__builtin_trap(); }\n", descriptor_); - if (SupportsArenas(descriptor_)) { - format( - "$deprecated_attr$void " - "${1$unsafe_arena_set_allocated_$name$$}$(\n" - " $type$* $name$) { __builtin_trap(); }\n" - "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { " - "__builtin_trap(); }\n", - descriptor_); - } return; } format( @@ -133,7 +130,7 @@ void MessageFieldGenerator::GenerateAccessorDeclarations( "$deprecated_attr$void ${1$set_allocated_$name$$}$" "($type$* $name$);\n", descriptor_); - if (IsFieldUsed(descriptor_, options_)) { + if (!IsFieldStripped(descriptor_, options_)) { format( "private:\n" "const $type$& ${1$_internal_$name$$}$() const;\n" @@ -141,14 +138,12 @@ void MessageFieldGenerator::GenerateAccessorDeclarations( "public:\n", descriptor_); } - if (SupportsArenas(descriptor_)) { - format( - "$deprecated_attr$void " - "${1$unsafe_arena_set_allocated_$name$$}$(\n" - " $type$* $name$);\n" - "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n", - descriptor_); - } + format( + "$deprecated_attr$void " + "${1$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$);\n" + "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n", + descriptor_); } void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( @@ -162,8 +157,8 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$() const {\n" "$type_reference_function$" " const $type$* p = $casted_member$;\n" - " return p != nullptr ? *p : *reinterpret_cast(\n" - " &$type_default_instance$);\n" + " return p != nullptr ? *p : reinterpret_cast(\n" + " $type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" "$annotate_accessor$" @@ -171,48 +166,43 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( " return _internal_$name$();\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$) {\n" - "$annotate_accessor$" - // If we're not on an arena, free whatever we were holding before. - // (If we are on arena, we can just forget the earlier pointer.) - " if (GetArena() == nullptr) {\n" - " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n" - " }\n"); - if (implicit_weak_field_) { - format( - " $name$_ = " - "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); - } else { - format(" $name$_ = $name$;\n"); - } - format( - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" - ":$full_name$)\n" - "}\n"); + format( + "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" + " $type$* $name$) {\n" + "$annotate_accessor$" + // If we're not on an arena, free whatever we were holding before. + // (If we are on arena, we can just forget the earlier pointer.) + " if (GetArena() == nullptr) {\n" + " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n" + " }\n"); + if (implicit_weak_field_) { format( - "inline $type$* $classname$::$release_name$() {\n" - "$type_reference_function$" - " $clear_hasbit$\n" - " $type$* temp = $casted_member$;\n" - " $name$_ = nullptr;\n" - " if (GetArena() != nullptr) {\n" - " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" - " }\n" - " return temp;\n" - "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"); + " $name$_ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); } else { - format("inline $type$* $classname$::$release_name$() {\n"); + format(" $name$_ = $name$;\n"); } format( + " if ($name$) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" + ":$full_name$)\n" + "}\n"); + format( + "inline $type$* $classname$::$release_name$() {\n" + "$type_reference_function$" + " $clear_hasbit$\n" + " $type$* temp = $casted_member$;\n" + " $name$_ = nullptr;\n" + " if (GetArena() != nullptr) {\n" + " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" + " }\n" + " return temp;\n" + "}\n" + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" "$annotate_accessor$" " // @@protoc_insertion_point(field_release:$full_name$)\n" "$type_reference_function$" @@ -259,16 +249,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( format( " }\n" " if ($name$) {\n"); - if (SupportsArenas(descriptor_->message_type()) && - IsCrossFileMessage(descriptor_)) { + if (IsCrossFileMessage(descriptor_)) { // We have to read the arena through the virtual method, because the type // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" " " "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n"); - } else if (!SupportsArenas(descriptor_->message_type())) { - format(" ::$proto_ns$::Arena* submessage_arena = nullptr;\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" @@ -330,48 +317,26 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n" " }\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "::$proto_ns$::MessageLite*\n" - "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); - if (HasFieldPresence(descriptor_->file())) { - format(" msg->$set_hasbit$\n"); - } - format( - " if (msg->$name$_ == nullptr) {\n" - " if ($type_default_instance_ptr$ == nullptr) {\n" - " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" - " ::$proto_ns$::internal::ImplicitWeakMessage>(\n" - " msg->GetArena());\n" - " } else {\n" - " msg->$name$_ = reinterpret_cast(\n" - " $type_default_instance_ptr$)->New(msg->GetArena());\n" - " }\n" - " }\n" - " return msg->$name$_;\n" - "}\n"); - } else { - format( - "::$proto_ns$::MessageLite*\n" - "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); - if (HasFieldPresence(descriptor_->file())) { - format(" msg->$set_hasbit$\n"); - } - format( - " if (msg->$name$_ == nullptr) {\n" - " if ($type_default_instance_ptr$ == nullptr) {\n" - " msg->$name$_ = " - "new ::$proto_ns$::internal::ImplicitWeakMessage;\n" - " } else {\n" - " msg->$name$_ = " - "reinterpret_cast(\n" - " $type_default_instance_ptr$)->New();\n" - " }\n" - " }\n" - " return msg->$name$_;\n" - "}\n"); + format( + "::$proto_ns$::MessageLite*\n" + "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); + if (HasFieldPresence(descriptor_->file())) { + format(" msg->$set_hasbit$\n"); } + format( + " if (msg->$name$_ == nullptr) {\n" + " if ($type_default_instance_ptr$ == nullptr) {\n" + " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" + " ::$proto_ns$::internal::ImplicitWeakMessage>(\n" + " msg->GetArena());\n" + " } else {\n" + " msg->$name$_ = reinterpret_cast(\n" + " $type_default_instance_ptr$)->New(msg->GetArena());\n" + " }\n" + " }\n" + " return msg->$name$_;\n" + "}\n"); } else { // This inline accessor directly returns member field and is used in // Serialize such that AFDO profile correctly captures access information to @@ -385,7 +350,7 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( } void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); if (!HasFieldPresence(descriptor_->file())) { @@ -403,7 +368,7 @@ void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { void MessageFieldGenerator::GenerateMessageClearingCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); if (!HasFieldPresence(descriptor_->file())) { @@ -422,7 +387,7 @@ void MessageFieldGenerator::GenerateMessageClearingCode( } void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); if (implicit_weak_field_) { @@ -437,14 +402,14 @@ void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const { } void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format("swap($name$_, other->$name$_);\n"); } void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); if (options_.opensource_runtime) { @@ -460,7 +425,7 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { void MessageFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format("$name$_ = nullptr;\n"); @@ -468,7 +433,7 @@ void MessageFieldGenerator::GenerateConstructorCode( void MessageFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format( @@ -481,7 +446,7 @@ void MessageFieldGenerator::GenerateCopyConstructorCode( void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format( @@ -492,7 +457,7 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( } void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format( @@ -521,16 +486,13 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( " ::$proto_ns$::Arena* message_arena = GetArena();\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); - if (SupportsArenas(descriptor_->message_type()) && - descriptor_->file() != descriptor_->message_type()->file()) { + if (descriptor_->file() != descriptor_->message_type()->file()) { // We have to read the arena through the virtual method, because the type // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" " " "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n"); - } else if (!SupportsArenas(descriptor_->message_type())) { - format(" ::$proto_ns$::Arena* submessage_arena = nullptr;\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" @@ -557,14 +519,10 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n"); - if (SupportsArenas(descriptor_)) { - format( - " if (GetArena() != nullptr) {\n" - " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" - " }\n"); - } - format( + " $type$* temp = $field_member$;\n" + " if (GetArena() != nullptr) {\n" + " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" + " }\n" " $field_member$ = nullptr;\n" " return temp;\n" " } else {\n" @@ -576,46 +534,40 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$() const {\n" " return _internal_has_$name$()\n" " ? *$field_member$\n" - " : *reinterpret_cast< $type$*>(&$type_default_instance$);\n" + " : reinterpret_cast< $type$&>($type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" "$annotate_accessor$" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return _internal_$name$();\n" - "}\n"); - - if (SupportsArenas(descriptor_)) { - format( - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_unsafe_arena_release" - ":$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" - " $field_member$ = nullptr;\n" - " return temp;\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$" - "($type$* $name$) {\n" - "$annotate_accessor$" - // We rely on the oneof clear method to free the earlier contents of - // this oneof. We can directly use the pointer we're given to set the - // new value. - " clear_$oneof_name$();\n" - " if ($name$) {\n" - " set_has_$name$();\n" - " $field_member$ = $name$;\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" - "$full_name$)\n" - "}\n"); - } - - format( + "}\n" + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_unsafe_arena_release" + ":$full_name$)\n" + " if (_internal_has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " $type$* temp = $field_member$;\n" + " $field_member$ = nullptr;\n" + " return temp;\n" + " } else {\n" + " return nullptr;\n" + " }\n" + "}\n" + "inline void $classname$::unsafe_arena_set_allocated_$name$" + "($type$* $name$) {\n" + "$annotate_accessor$" + // We rely on the oneof clear method to free the earlier contents of + // this oneof. We can directly use the pointer we're given to set the + // new value. + " clear_$oneof_name$();\n" + " if ($name$) {\n" + " set_has_$name$();\n" + " $field_member$ = $name$;\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" + "$full_name$)\n" + "}\n" "inline $type$* $classname$::_internal_mutable_$name$() {\n" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" @@ -633,17 +585,13 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( void MessageOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - if (SupportsArenas(descriptor_)) { - format( - "if (GetArena() == nullptr) {\n" - " delete $field_member$;\n" - "}\n"); - } else { - format("delete $field_member$;\n"); - } + format( + "if (GetArena() == nullptr) {\n" + " delete $field_member$;\n" + "}\n"); } void MessageOneofFieldGenerator::GenerateMessageClearingCode( @@ -694,7 +642,7 @@ void RepeatedMessageFieldGenerator::GeneratePrivateMembers( void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations( io::Printer* printer) const { Formatter format(printer, variables_); - if (!IsFieldUsed(descriptor_, options_)) { + if (IsFieldStripped(descriptor_, options_)) { format( "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { " "__builtin_trap(); }\n" @@ -714,7 +662,7 @@ void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations( "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n" " ${1$mutable_$name$$}$();\n", descriptor_); - if (IsFieldUsed(descriptor_, options_)) { + if (!IsFieldStripped(descriptor_, options_)) { format( "private:\n" "const $type$& ${1$_internal_$name$$}$(int index) const;\n" @@ -756,7 +704,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" " return $name$_$weak$.InternalCheckedGet(index,\n" - " *reinterpret_cast(&$type_default_instance$));\n" + " reinterpret_cast($type_default_instance$));\n" "}\n"); } else { format( @@ -794,7 +742,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedMessageFieldGenerator::GenerateClearingCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format("$name$_.Clear();\n"); @@ -802,7 +750,7 @@ void RepeatedMessageFieldGenerator::GenerateClearingCode( void RepeatedMessageFieldGenerator::GenerateMergingCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format("$name$_.MergeFrom(from.$name$_);\n"); @@ -810,7 +758,7 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode( void RepeatedMessageFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format("$name$_.InternalSwap(&other->$name$_);\n"); @@ -823,7 +771,7 @@ void RepeatedMessageFieldGenerator::GenerateConstructorCode( void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); if (implicit_weak_field_) { @@ -850,7 +798,7 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( void RepeatedMessageFieldGenerator::GenerateByteSize( io::Printer* printer) const { - GOOGLE_CHECK(IsFieldUsed(descriptor_, options_)); + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); format( diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 5cf82f6de2..9acc447983 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -99,18 +99,6 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { if (inlined_) { format("::$proto_ns$::internal::InlinedStringField $name$_;\n"); } else { - // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for - // string fields, even when SupportArenas(descriptor_) == false. Why? The - // simple answer is to avoid unmaintainable complexity. The reflection code - // assumes ArenaStringPtrs. These are *almost* in-memory-compatible with - // string*, except for the pointer tags and related ownership semantics. We - // could modify the runtime code to use string* for the - // not-supporting-arenas case, but this would require a way to detect which - // type of class was generated (adding overhead and complexity to - // GeneratedMessageReflection) and littering the runtime code paths with - // conditionals. It's simpler to stick with this but use lightweight - // accessors that assume arena == NULL. There should be very little - // overhead anyway because it's just a tagged pointer in-memory. format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); } } @@ -211,163 +199,82 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_accessor$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return _internal_mutable_$name$();\n" + "}\n" + "inline const std::string& $classname$::_internal_$name$() const {\n" + " return $name$_.Get();\n" + "}\n" + "inline void $classname$::_internal_set_$name$(const std::string& " + "value) {\n" + " $set_hasbit$\n" + " $name$_.Set$lite$($default_variable$, value, GetArena());\n" + "}\n" + "inline void $classname$::set_$name$(std::string&& value) {\n" + "$annotate_accessor$" + " $set_hasbit$\n" + " $name$_.Set$lite$(\n" + " $default_variable$, ::std::move(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + "$annotate_accessor$" + " $null_check$" + " $set_hasbit$\n" + " $name$_.Set$lite$($default_variable$, $string_piece$(value),\n" + " GetArena());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); - if (SupportsArenas(descriptor_)) { + if (!options_.opensource_runtime) { format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.Get();\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value, GetArena());\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArena());\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "inline void $classname$::set_$name$(::StringPiece value) {\n" "$annotate_accessor$" - " $null_check$" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(value),\n" - " GetArena());\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + " $name$_.Set$lite$($default_variable$, value,GetArena());\n" + " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value,GetArena());\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value,\n" - " size_t size) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size), GetArena());\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " $set_hasbit$\n" - " return $name$_.Mutable($default_variable$, GetArena());\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n"); - - if (HasHasbit(descriptor_)) { - format( - " if (!_internal_has_$name$()) {\n" - " return nullptr;\n" - " }\n" - " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefault(" - "$default_variable$, GetArena());\n"); - } else { - format( - " return $name$_.Release($default_variable$, GetArena());\n"); - } + } + format( + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + "$annotate_accessor$" + " $set_hasbit$\n" + " $name$_.Set$lite$($default_variable$, $string_piece$(\n" + " reinterpret_cast(value), size), GetArena());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline std::string* $classname$::_internal_mutable_$name$() {\n" + " $set_hasbit$\n" + " return $name$_.Mutable($default_variable$, GetArena());\n" + "}\n" + "inline std::string* $classname$::$release_name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_release:$full_name$)\n"); + if (HasHasbit(descriptor_)) { format( - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if ($name$ != nullptr) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" + " if (!_internal_has_$name$()) {\n" + " return nullptr;\n" " }\n" - " $name$_.SetAllocated($default_variable$, $name$,\n" - " GetArena());\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); + " $clear_hasbit$\n" + " return $name$_.ReleaseNonDefault(" + "$default_variable$, GetArena());\n"); } else { - // No-arena case. - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.GetNoArena();\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, value);\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena(\n" - " $default_variable$, ::std::move(value));\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, value);\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, " - "size_t size) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$,\n" - " $string_piece$(reinterpret_cast(value), size));\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " $set_hasbit$\n" - " return $name$_.MutableNoArena($default_variable$);\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n"); - - if (HasHasbit(descriptor_)) { - format( - " if (!_internal_has_$name$()) {\n" - " return nullptr;\n" - " }\n" - " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n"); - } else { - format( - " $clear_hasbit$\n" - " return $name$_.ReleaseNoArena($default_variable$);\n"); - } - - format( - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if ($name$ != nullptr) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " $name$_.SetAllocatedNoArena($default_variable$, $name$);\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); + format(" return $name$_.Release($default_variable$, GetArena());\n"); } + + format( + "}\n" + "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" + "$annotate_accessor$" + " if ($name$ != nullptr) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " $name$_.SetAllocated($default_variable$, $name$,\n" + " GetArena());\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( @@ -387,18 +294,10 @@ void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const { // value is the empty string or not. Complexity here ensures the minimal // number of branches / amount of extraneous code at runtime (given that the // below methods are inlined one-liners)! - if (SupportsArenas(descriptor_)) { - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); - } else { - format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); - } + if (descriptor_->default_value_string().empty()) { + format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); } else { - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmptyNoArena($default_variable$);\n"); - } else { - format("$name$_.ClearToDefaultNoArena($default_variable$);\n"); - } + format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); } } @@ -427,45 +326,23 @@ void StringFieldGenerator::GenerateMessageClearingCode( format("$DCHK$(!$name$_.IsDefault($default_variable$));\n"); } - if (SupportsArenas(descriptor_)) { - if (descriptor_->default_value_string().empty()) { - if (must_be_present) { - format("$name$_.ClearNonDefaultToEmpty();\n"); - } else { - format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); - } - } else { - // Clear to a non-empty default is more involved, as we try to use the - // Arena if one is present and may need to reallocate the string. - format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); - } - } else if (must_be_present) { - // When Arenas are disabled and field presence has been checked, we can - // safely treat the ArenaStringPtr as a string*. - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearNonDefaultToEmptyNoArena();\n"); + if (descriptor_->default_value_string().empty()) { + if (must_be_present) { + format("$name$_.ClearNonDefaultToEmpty();\n"); } else { - format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n"); + format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); } } else { - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmptyNoArena($default_variable$);\n"); - } else { - format("$name$_.ClearToDefaultNoArena($default_variable$);\n"); - } + // Clear to a non-empty default is more involved, as we try to use the + // Arena if one is present and may need to reallocate the string. + format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); } } void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) { - // TODO(gpike): improve this - format("_internal_set_$name$(from._internal_$name$());\n"); - } else { - format( - "$set_hasbit$\n" - "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n"); - } + // TODO(gpike): improve this + format("_internal_set_$name$(from._internal_$name$());\n"); } void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { @@ -502,14 +379,10 @@ void StringFieldGenerator::GenerateCopyConstructorCode( format.Indent(); - if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) { - // TODO(gpike): improve this - format( - "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n" - " GetArena());\n"); - } else { - format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n"); - } + // TODO(gpike): improve this + format( + "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n" + " GetArena());\n"); format.Outdent(); format("}\n"); @@ -613,219 +486,115 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_accessor$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return _internal_mutable_$name$();\n" + "}\n" + "inline const std::string& $classname$::_internal_$name$() const {\n" + " if (_internal_has_$name$()) {\n" + " return $field_member$.Get();\n" + " }\n" + " return *$default_variable$;\n" + "}\n" + "inline void $classname$::_internal_set_$name$(const std::string& " + "value) {\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $field_member$.Set$lite$($default_variable$, value, GetArena());\n" + "}\n" + "inline void $classname$::set_$name$(std::string&& value) {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $field_member$.Set$lite$(\n" + " $default_variable$, ::std::move(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + "$annotate_accessor$" + " $null_check$" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $field_member$.Set$lite$($default_variable$,\n" + " $string_piece$(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " if (_internal_has_$name$()) {\n" - " return $field_member$.Get();\n" - " }\n" - " return *$default_variable$;\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$, value, GetArena());\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArena());\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$,\n" - " $string_piece$(value), GetArena());\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$, value,\n" - " GetArena());\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } + if (!options_.opensource_runtime) { format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value,\n" - " size_t size) {\n" + "inline void $classname$::set_$name$(::StringPiece value) {\n" "$annotate_accessor$" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size),\n" + " $field_member$.Set$lite$($default_variable$, value,\n" " GetArena());\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " return $field_member$.Mutable($default_variable$, GetArena());\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " return $field_member$.Release($default_variable$, GetArena());\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if (has_$oneof_name$()) {\n" - " clear_$oneof_name$();\n" - " }\n" - " if ($name$ != nullptr) {\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " ::$proto_ns$::Arena* arena = GetArena();\n" - " if (arena != nullptr) {\n" - " arena->Own($name$);\n" - " }\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); - } else { - // No-arena case. - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " if (_internal_has_$name$()) {\n" - " return $field_member$.GetNoArena();\n" - " }\n" - " return *$default_variable$;\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, value);\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, ::std::move(value));\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$,\n" - " $string_piece$(value));\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, value);\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, size_t " - "size) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size));\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " return $field_member$.MutableNoArena($default_variable$);\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " return $field_member$.ReleaseNoArena($default_variable$);\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if (has_$oneof_name$()) {\n" - " clear_$oneof_name$();\n" - " }\n" - " if ($name$ != nullptr) {\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); } + format( + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + "$annotate_accessor$" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $field_member$.Set$lite$(\n" + " $default_variable$, $string_piece$(\n" + " reinterpret_cast(value), size),\n" + " GetArena());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline std::string* $classname$::_internal_mutable_$name$() {\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " return $field_member$.Mutable($default_variable$, GetArena());\n" + "}\n" + "inline std::string* $classname$::$release_name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_release:$full_name$)\n" + " if (_internal_has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " return $field_member$.Release($default_variable$, GetArena());\n" + " } else {\n" + " return nullptr;\n" + " }\n" + "}\n" + "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" + "$annotate_accessor$" + " if (has_$oneof_name$()) {\n" + " clear_$oneof_name$();\n" + " }\n" + " if ($name$ != nullptr) {\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($name$);\n" + " ::$proto_ns$::Arena* arena = GetArena();\n" + " if (arena != nullptr) {\n" + " arena->Own($name$);\n" + " }\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void StringOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - if (SupportsArenas(descriptor_)) { - format("$field_member$.Destroy($default_variable$, GetArena());\n"); - } else { - format("$field_member$.DestroyNoArena($default_variable$);\n"); - } + format("$field_member$.Destroy($default_variable$, GetArena());\n"); } void StringOneofFieldGenerator::GenerateMessageClearingCode( diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index ab5c356901..1ff8aadc6f 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -495,7 +495,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( do { ret = stat(filename.c_str(), &sb); } while (ret != 0 && errno == EINTR); - if (sb.st_mode & S_IFDIR) { + if (ret == 0 && sb.st_mode & S_IFDIR) { last_error_message_ = "Input file is a directory."; return NULL; } diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 0b85056138..b463622d4a 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -166,17 +166,36 @@ void MockCodeGenerator::CheckGeneratedAnnotations( &file_content, true)); std::string meta_content; GOOGLE_CHECK_OK(File::GetContents( - output_directory + "/" + GetOutputFileName(name, file) + ".meta", + output_directory + "/" + GetOutputFileName(name, file) + ".pb.meta", &meta_content, true)); GeneratedCodeInfo annotations; GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations)); - ASSERT_EQ(3, annotations.annotation_size()); + ASSERT_EQ(7, annotations.annotation_size()); + CheckSingleAnnotation("first_annotation", "first", file_content, annotations.annotation(0)); + CheckSingleAnnotation("first_path", + "test_generator: first_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(1)); + CheckSingleAnnotation("first_path", + "test_plugin: first_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(2)); CheckSingleAnnotation("second_annotation", "second", file_content, - annotations.annotation(1)); + annotations.annotation(3)); + // This annotated text has changed because it was inserted at an indented + // insertion point. + CheckSingleAnnotation("second_path", + "test_generator: second_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(4)); + CheckSingleAnnotation("second_path", + "test_plugin: second_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(5)); CheckSingleAnnotation("third_annotation", "third", file_content, - annotations.annotation(2)); + annotations.annotation(6)); } bool MockCodeGenerator::Generate(const FileDescriptor* file, @@ -229,18 +248,35 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } } - if (HasPrefixString(parameter, "insert=")) { + bool insert_endlines = HasPrefixString(parameter, "insert_endlines="); + if (insert_endlines || HasPrefixString(parameter, "insert=")) { std::vector insert_into; - SplitStringUsing(StripPrefixString(parameter, "insert="), ",", - &insert_into); + + SplitStringUsing( + StripPrefixString( + parameter, insert_endlines ? "insert_endlines=" : "insert="), + ",", &insert_into); for (size_t i = 0; i < insert_into.size(); i++) { { - std::unique_ptr output(context->OpenForInsert( - GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); + google::protobuf::GeneratedCodeInfo info; + std::string content = + GetOutputFileContent(name_, "first_insert", file, context); + if (insert_endlines) { + GlobalReplaceSubstring(",", ",\n", &content); + } + if (annotate) { + auto* annotation = info.add_annotation(); + annotation->set_begin(0); + annotation->set_end(content.size()); + annotation->set_source_file("first_path"); + } + std::unique_ptr output( + context->OpenForInsertWithGeneratedCodeInfo( + GetOutputFileName(insert_into[i], file), + kFirstInsertionPointName, info)); io::Printer printer(output.get(), '$'); - printer.PrintRaw( - GetOutputFileContent(name_, "first_insert", file, context)); + printer.PrintRaw(content); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -248,12 +284,24 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } { + google::protobuf::GeneratedCodeInfo info; + std::string content = + GetOutputFileContent(name_, "second_insert", file, context); + if (insert_endlines) { + GlobalReplaceSubstring(",", ",\n", &content); + } + if (annotate) { + auto* annotation = info.add_annotation(); + annotation->set_begin(0); + annotation->set_end(content.size()); + annotation->set_source_file("second_path"); + } std::unique_ptr output( - context->OpenForInsert(GetOutputFileName(insert_into[i], file), - kSecondInsertionPointName)); + context->OpenForInsertWithGeneratedCodeInfo( + GetOutputFileName(insert_into[i], file), + kSecondInsertionPointName, info)); io::Printer printer(output.get(), '$'); - printer.PrintRaw( - GetOutputFileContent(name_, "second_insert", file, context)); + printer.PrintRaw(content); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -272,17 +320,17 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); std::string annotate_suffix = "_annotation"; if (annotate) { - printer.Print("$p$", "p", "first"); + printer.Print("$p$\n", "p", "first"); printer.Annotate("p", "first" + annotate_suffix); } printer.PrintRaw(kFirstInsertionPoint); if (annotate) { - printer.Print("$p$", "p", "second"); + printer.Print("$p$\n", "p", "second"); printer.Annotate("p", "second" + annotate_suffix); } printer.PrintRaw(kSecondInsertionPoint); if (annotate) { - printer.Print("$p$", "p", "third"); + printer.Print("$p$\n", "p", "third"); printer.Annotate("p", "third" + annotate_suffix); } @@ -292,9 +340,9 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } if (annotate) { std::unique_ptr meta_output( - context->Open(GetOutputFileName(name_, file) + ".meta")); + context->Open(GetOutputFileName(name_, file) + ".pb.meta")); if (!TextFormat::Print(annotations, meta_output.get())) { - *error = "MockCodeGenerator couldn't write .meta"; + *error = "MockCodeGenerator couldn't write .pb.meta"; return false; } } diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 9a72258694..9677d1904d 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -56,7 +56,9 @@ namespace compiler { // If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines // into the files generated by other MockCodeGenerators instead of creating // its own file. NAMES is a comma-separated list of the names of those other -// MockCodeGenerators. +// MockCodeGenerators. If the parameter is "insert_endlines=NAMES", the +// MockCodeGenerator will insert data guaranteed to contain more than one +// endline into the files generated by NAMES. // // MockCodeGenerator will also modify its behavior slightly if the input file // contains a message type with one of the following names: diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index 58ca9c195b..ce4a12c987 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -421,7 +421,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"); if (includes_oneof) { // The generated code for oneof's uses direct ivar access, suppress the - // warning incase developer turn that on in the context they compile the + // warning in case developer turn that on in the context they compile the // generated code. printer->Print( "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n"); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 257e4f9abc..a1a6f529e4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -29,12 +29,12 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include #include #include #include -#include namespace google { namespace protobuf { @@ -93,8 +93,11 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. - SplitStringUsing(options[i].second, ";", - &generation_options.expected_prefixes_suppressions); + for (StringPiece split_piece : Split( + options[i].second, ";", true)) { + generation_options.expected_prefixes_suppressions.push_back( + std::string(split_piece)); + } } else if (options[i].first == "generate_for_named_framework") { // The name of the framework that protos are being generated for. This // will cause the #import statements to be framework based using this @@ -120,7 +123,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& // Any number of files can be listed for a framework, just separate them // with commas. // - // There can be multiple lines listing the same frameworkName incase it + // There can be multiple lines listing the same frameworkName in case it // has a lot of proto files included in it; having multiple lines makes // things easier to read. If a proto file is not configured in the // mappings file, it will use the default framework name if one was passed diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 8b2b719e03..77fe084b73 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -78,7 +78,8 @@ Options::Options() { } const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS"); if (suppressions) { - SplitStringUsing(suppressions, ";", &expected_prefixes_suppressions); + expected_prefixes_suppressions = + Split(suppressions, ";", true); } } diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 4a6206a0f2..365cb64e53 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -624,21 +624,17 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer, printer->Print( "private $^name^;\n", "name", field->name()); - } else if (field->containing_oneof()) { + } else if (field->real_containing_oneof()) { // Oneof fields are handled by GenerateOneofField. return; } else { + std::string initial_value = + field->has_presence() ? "null" : DefaultForField(field); GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); printer->Print( - "protected $^name^ = ^default^;\n", + "protected $^name^ = ^initial_value^;\n", "name", field->name(), - "default", DefaultForField(field)); - } - - if (is_descriptor) { - printer->Print( - "private $has_^name^ = false;\n", - "name", field->name()); + "initial_value", initial_value); } } @@ -652,20 +648,41 @@ void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) { void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, io::Printer* printer) { - const OneofDescriptor* oneof = field->containing_oneof(); + const OneofDescriptor* oneof = field->real_containing_oneof(); // Generate getter. + GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); + if (oneof != NULL) { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" " return $this->readOneof(^number^);\n" + "}\n\n" + "public function has^camel_name^()\n" + "{\n" + " return $this->hasOneof(^number^);\n" "}\n\n", "camel_name", UnderscoresToCamelCase(field->name(), true), "number", IntToString(field->number())); + } else if (field->has_presence()) { + printer->Print( + "public function get^camel_name^()\n" + "{\n" + " return isset($this->^name^) ? $this->^name^ : ^default_value^;\n" + "}\n\n" + "public function has^camel_name^()\n" + "{\n" + " return isset($this->^name^);\n" + "}\n\n" + "public function clear^camel_name^()\n" + "{\n" + " unset($this->^name^);\n" + "}\n\n", + "camel_name", UnderscoresToCamelCase(field->name(), true), + "name", field->name(), + "default_value", DefaultForField(field)); } else { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" @@ -774,13 +791,6 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, "name", field->name()); } - // Set has bit for proto2 only. - if (is_descriptor) { - printer->Print( - "$this->has_^field_name^ = true;\n", - "field_name", field->name()); - } - printer->Print("\nreturn $this;\n"); Outdent(printer); @@ -803,17 +813,6 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, "camel_name", UnderscoresToCamelCase(field->name(), true), "field_name", field->name()); } - - // Generate has method for proto2 only. - if (is_descriptor) { - printer->Print( - "public function has^camel_name^()\n" - "{\n" - " return $this->has_^field_name^;\n" - "}\n\n", - "camel_name", UnderscoresToCamelCase(field->name(), true), - "field_name", field->name()); - } } void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { @@ -878,7 +877,7 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, "value", ToUpper(val->type_name()), "number", StrCat(field->number()), "other", EnumOrMessageSuffix(val, true)); - } else if (!field->containing_oneof()) { + } else if (!field->real_containing_oneof()) { printer->Print( "->^label^('^field^', " "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n", @@ -891,7 +890,7 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, } // oneofs. - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); printer->Print("->oneof(^name^)\n", "name", oneof->name()); @@ -1414,7 +1413,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, const FieldDescriptor* field = message->field(i); GenerateField(field, &printer, is_descriptor); } - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); GenerateOneofField(oneof, &printer); } @@ -1443,7 +1442,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, const FieldDescriptor* field = message->field(i); GenerateFieldAccessor(field, is_descriptor, &printer); } - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); printer.Print( "/**\n" diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index ca9d23a46a..f67bb40417 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -55,6 +55,11 @@ class PROTOC_EXPORT Generator : public CodeGenerator { const std::string& parameter, GeneratorContext* generator_context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } + private: bool Generate( const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 7306cf4449..cb7801d53c 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -86,6 +86,16 @@ class GeneratorResponseContext : public GeneratorContext { return new io::StringOutputStream(file->mutable_content()); } + virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + file->set_insertion_point(insertion_point); + *file->mutable_generated_code_info() = info; + return new io::StringOutputStream(file->mutable_content()); + } + void ListParsedFiles(std::vector* output) { *output = parsed_files_; } diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index c2e430acda..2b39bc40e3 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -15,7 +15,8 @@ // @@protoc_insertion_point(includes) #include extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto; PROTOBUF_NAMESPACE_OPEN namespace compiler { @@ -45,7 +46,6 @@ static void InitDefaultsscc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompil new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto = @@ -61,7 +61,6 @@ static void InitDefaultsscc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompi new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto = @@ -76,11 +75,11 @@ static void InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2f new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance(); } -PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}}; +PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, { + &scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base,}}; static void InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -90,7 +89,6 @@ static void InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2 new (ptr) PROTOBUF_NAMESPACE_ID::compiler::Version(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::Version::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto = @@ -135,9 +133,11 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fcompiler_2 PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_), + PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, generated_code_info_), 0, 1, 2, + 3, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _internal_metadata_), ~0u, // no _extensions_ @@ -153,8 +153,8 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fcompiler_2 static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, 9, sizeof(PROTOBUF_NAMESPACE_ID::compiler::Version)}, { 13, 22, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, - { 26, 34, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, - { 37, 45, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, + { 26, 35, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, + { 39, 47, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -174,15 +174,17 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf." "FileDescriptorProto\022;\n\020compiler_version\030" "\003 \001(\0132!.google.protobuf.compiler.Version" - "\"\200\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001(" + "\"\301\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001(" "\t\022\032\n\022supported_features\030\002 \001(\004\022B\n\004file\030\017 " "\003(\01324.google.protobuf.compiler.CodeGener" - "atorResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022" + "atorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022" "\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(" - "\t\"8\n\007Feature\022\020\n\014FEATURE_NONE\020\000\022\033\n\027FEATUR" - "E_PROTO3_OPTIONAL\020\001BW\n\034com.google.protob" - "uf.compilerB\014PluginProtosZ)google.golang" - ".org/protobuf/types/pluginpb" + "\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google." + "protobuf.GeneratedCodeInfo\"8\n\007Feature\022\020\n" + "\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTION" + "AL\020\001BW\n\034com.google.protobuf.compilerB\014Pl" + "uginProtosZ)google.golang.org/protobuf/t" + "ypes/pluginpb" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, @@ -195,7 +197,7 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { - false, false, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 708, + false, false, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 773, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_sccs, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 4, 1, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, @@ -229,8 +231,6 @@ constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE; // =================================================================== -void Version::InitAsDefaultInstance() { -} class Version::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -558,10 +558,6 @@ void Version::InternalSwap(Version* other) { // =================================================================== -void CodeGeneratorRequest::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< PROTOBUF_NAMESPACE_ID::compiler::Version*>( - PROTOBUF_NAMESPACE_ID::compiler::Version::internal_default_instance()); -} class CodeGeneratorRequest::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -912,8 +908,6 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { // =================================================================== -void CodeGeneratorResponse_File::InitAsDefaultInstance() { -} class CodeGeneratorResponse_File::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -926,8 +920,20 @@ class CodeGeneratorResponse_File::_Internal { static void set_has_content(HasBits* has_bits) { (*has_bits)[0] |= 4u; } + static const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info(const CodeGeneratorResponse_File* msg); + static void set_has_generated_code_info(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } }; +const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& +CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) { + return *msg->generated_code_info_; +} +void CodeGeneratorResponse_File::clear_generated_code_info() { + if (generated_code_info_ != nullptr) generated_code_info_->Clear(); + _has_bits_[0] &= ~0x00000008u; +} CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena) : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); @@ -953,6 +959,11 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_content(), GetArena()); } + if (from._internal_has_generated_code_info()) { + generated_code_info_ = new PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from.generated_code_info_); + } else { + generated_code_info_ = nullptr; + } // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } @@ -961,6 +972,7 @@ void CodeGeneratorResponse_File::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + generated_code_info_ = nullptr; } CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { @@ -974,6 +986,7 @@ void CodeGeneratorResponse_File::SharedDtor() { name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete generated_code_info_; } void CodeGeneratorResponse_File::ArenaDtor(void* object) { @@ -998,7 +1011,7 @@ void CodeGeneratorResponse_File::Clear() { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { name_.ClearNonDefaultToEmpty(); } @@ -1008,6 +1021,10 @@ void CodeGeneratorResponse_File::Clear() { if (cached_has_bits & 0x00000004u) { content_.ClearNonDefaultToEmpty(); } + if (cached_has_bits & 0x00000008u) { + GOOGLE_DCHECK(generated_code_info_ != nullptr); + generated_code_info_->Clear(); + } } _has_bits_.Clear(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); @@ -1055,6 +1072,13 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB CHK_(ptr); } else goto handle_unusual; continue; + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + case 16: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) { + ptr = ctx->ParseMessage(_internal_mutable_generated_code_info(), ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { @@ -1115,6 +1139,14 @@ failure: 15, this->_internal_content(), target); } + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 16, _Internal::generated_code_info(this), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); @@ -1132,7 +1164,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { // optional string name = 1; if (cached_has_bits & 0x00000001u) { total_size += 1 + @@ -1154,6 +1186,13 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { this->_internal_content()); } + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + if (cached_has_bits & 0x00000008u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *generated_code_info_); + } + } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( @@ -1187,7 +1226,7 @@ void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& fro (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { _internal_set_name(from._internal_name()); } @@ -1197,6 +1236,9 @@ void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& fro if (cached_has_bits & 0x00000004u) { _internal_set_content(from._internal_content()); } + if (cached_has_bits & 0x00000008u) { + _internal_mutable_generated_code_info()->PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info()); + } } } @@ -1225,6 +1267,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); insertion_point_.Swap(&other->insertion_point_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); content_.Swap(&other->content_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + swap(generated_code_info_, other->generated_code_info_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const { @@ -1234,8 +1277,6 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) // =================================================================== -void CodeGeneratorResponse::InitAsDefaultInstance() { -} class CodeGeneratorResponse::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 77d45ebfad..8ee850de61 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -155,7 +155,6 @@ class PROTOC_EXPORT Version PROTOBUF_FINAL : } static const Version& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Version* internal_default_instance() { return reinterpret_cast( &_Version_default_instance_); @@ -356,7 +355,6 @@ class PROTOC_EXPORT CodeGeneratorRequest PROTOBUF_FINAL : } static const CodeGeneratorRequest& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorRequest* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorRequest_default_instance_); @@ -578,7 +576,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL : } static const CodeGeneratorResponse_File& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse_File* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorResponse_File_default_instance_); @@ -658,6 +655,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL : kNameFieldNumber = 1, kInsertionPointFieldNumber = 2, kContentFieldNumber = 15, + kGeneratedCodeInfoFieldNumber = 16, }; // optional string name = 1; bool has_name() const; @@ -719,6 +717,24 @@ class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL : std::string* _internal_mutable_content(); public: + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + bool has_generated_code_info() const; + private: + bool _internal_has_generated_code_info() const; + public: + void clear_generated_code_info(); + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info(); + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info(); + void set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info); + private: + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& _internal_generated_code_info() const; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _internal_mutable_generated_code_info(); + public: + void unsafe_arena_set_allocated_generated_code_info( + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info); + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* unsafe_arena_release_generated_code_info(); + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: class _Internal; @@ -731,6 +747,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL : ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // ------------------------------------------------------------------- @@ -778,7 +795,6 @@ class PROTOC_EXPORT CodeGeneratorResponse PROTOBUF_FINAL : } static const CodeGeneratorResponse& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorResponse_default_instance_); @@ -1328,8 +1344,8 @@ inline void CodeGeneratorRequest::clear_compiler_version() { } inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const { const PROTOBUF_NAMESPACE_ID::compiler::Version* p = compiler_version_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::compiler_version() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) @@ -1622,6 +1638,85 @@ inline void CodeGeneratorResponse_File::set_allocated_content(std::string* conte // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) } +// optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; +inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + PROTOBUF_ASSUME(!value || generated_code_info_ != nullptr); + return value; +} +inline bool CodeGeneratorResponse_File::has_generated_code_info() const { + return _internal_has_generated_code_info(); +} +inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const { + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = generated_code_info_; + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_); +} +inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + return _internal_generated_code_info(); +} +inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info( + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + } + generated_code_info_ = generated_code_info; + if (generated_code_info) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() { + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; + generated_code_info_ = nullptr; + if (GetArena() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + return temp; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; + generated_code_info_ = nullptr; + return temp; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() { + _has_bits_[0] |= 0x00000008u; + if (generated_code_info_ == nullptr) { + auto* p = CreateMaybeMessage(GetArena()); + generated_code_info_ = p; + } + return generated_code_info_; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + return _internal_mutable_generated_code_info(); +} +inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + } + if (generated_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)->GetArena(); + if (message_arena != submessage_arena) { + generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, generated_code_info, submessage_arena); + } + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + generated_code_info_ = generated_code_info; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) +} + // ------------------------------------------------------------------- // CodeGeneratorResponse diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index 189db19429..9242aacc5b 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -173,6 +173,11 @@ message CodeGeneratorResponse { // The file contents. optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; } repeated File file = 15; } diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index cf61d9995a..ebc972c148 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -113,7 +113,7 @@ std::string TypeName(const FieldDescriptor* field) { } } -string StringifySyntax(FileDescriptor::Syntax syntax) { +std::string StringifySyntax(FileDescriptor::Syntax syntax) { switch (syntax) { case FileDescriptor::SYNTAX_PROTO2: return "proto2"; @@ -147,7 +147,7 @@ std::string DefaultValueForField(const FieldDescriptor* field) { return NumberToString(field->default_value_enum()->number()); case FieldDescriptor::CPPTYPE_STRING: { std::ostringstream os; - string default_str = field->default_value_string(); + std::string default_str = field->default_value_string(); if (field->type() == FieldDescriptor::TYPE_STRING) { os << "\"" << default_str << "\""; @@ -413,7 +413,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { // If :: is in the package use the Ruby formatted name as-is // -> A::B::C - // otherwise, use the dot seperator + // otherwise, use the dot separator // -> A.B.C if (package_name.find("::") != std::string::npos) { need_change_to_module = false; @@ -426,14 +426,14 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { } // Use the appropriate delimiter - string delimiter = need_change_to_module ? "." : "::"; + std::string delimiter = need_change_to_module ? "." : "::"; int delimiter_size = need_change_to_module ? 1 : 2; // Extract each module name and indent while (!package_name.empty()) { size_t dot_index = package_name.find(delimiter); - string component; - if (dot_index == string::npos) { + std::string component; + if (dot_index == std::string::npos) { component = package_name; package_name = ""; } else { @@ -462,7 +462,7 @@ void EndPackageModules(int levels, io::Printer* printer) { } bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file, - string* error) { + std::string* error) { for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && @@ -499,7 +499,7 @@ bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file, bool MaybeEmitDependency(const FileDescriptor* import, const FileDescriptor* from, io::Printer* printer, - string* error) { + std::string* error) { if (from->syntax() == FileDescriptor::SYNTAX_PROTO3 && import->syntax() == FileDescriptor::SYNTAX_PROTO2) { for (int i = 0; i < from->message_type_count(); i++) { @@ -524,7 +524,7 @@ bool MaybeEmitDependency(const FileDescriptor* import, } bool GenerateFile(const FileDescriptor* file, io::Printer* printer, - string* error) { + std::string* error) { printer->Print( "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" "# source: $filename$\n" @@ -580,9 +580,9 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, bool Generator::Generate( const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const { + std::string* error) const { if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 && file->syntax() != FileDescriptor::SYNTAX_PROTO2) { diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.h b/src/google/protobuf/compiler/ruby/ruby_generator.h index b40fcd01dd..647bb83606 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.h +++ b/src/google/protobuf/compiler/ruby/ruby_generator.h @@ -49,9 +49,9 @@ namespace ruby { // Ruby output, you can do so by registering an instance of this // CodeGenerator with the CommandLineInterface in your main() function. class PROTOC_EXPORT Generator : public CodeGenerator { - bool Generate(const FileDescriptor* file, const string& parameter, + bool Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, - string* error) const override; + std::string* error) const override; uint64_t GetSupportedFeatures() const override { return FEATURE_PROTO3_OPTIONAL; } @@ -65,4 +65,3 @@ class PROTOC_EXPORT Generator : public CodeGenerator { #include #endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ - diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 9a448ffc80..8fb9671896 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -2723,7 +2723,7 @@ void FieldDescriptor::DebugString( if (has_json_name_) { if (!bracketed) { bracketed = true; - contents->append("["); + contents->append(" ["); } else { contents->append(", "); } @@ -4883,6 +4883,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, DescriptorPool::ErrorCollector::DEFAULT_VALUE, "Messages can't have default values."); result->has_default_value_ = false; + result->default_generated_instance_ = nullptr; break; } @@ -4929,6 +4930,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->default_value_string_ = &internal::GetEmptyString(); break; case FieldDescriptor::CPPTYPE_MESSAGE: + result->default_generated_instance_ = nullptr; break; } } diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 078f24a68b..5bfecf5089 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -54,6 +54,7 @@ #ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ #define GOOGLE_PROTOBUF_DESCRIPTOR_H__ +#include #include #include #include @@ -839,6 +840,7 @@ class PROTOBUF_EXPORT FieldDescriptor { // Allows access to GetLocationPath for annotations. friend class io::Printer; friend class compiler::cpp::Formatter; + friend class Reflection; // Fill the json_name field of FieldDescriptorProto. void CopyJsonNameTo(FieldDescriptorProto* proto) const; @@ -906,6 +908,7 @@ class PROTOBUF_EXPORT FieldDescriptor { mutable const EnumValueDescriptor* default_value_enum_; const std::string* default_value_string_; + mutable std::atomic default_generated_instance_; }; static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; @@ -1235,6 +1238,7 @@ class PROTOBUF_EXPORT EnumValueDescriptor { friend class EnumDescriptor; friend class DescriptorPool; friend class FileDescriptorTables; + friend class Reflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); }; @@ -1857,7 +1861,7 @@ class PROTOBUF_EXPORT DescriptorPool { // Delay the building of dependencies of a file descriptor until absolutely // necessary, like when message_type() is called on a field that is defined // in that dependency's file. This will cause functional issues if a proto - // or one of it's dependencies has errors. Should only be enabled for the + // or one of its dependencies has errors. Should only be enabled for the // generated_pool_ (because no descriptor build errors are guaranteed by // the compilation generation process), testing, or if a lack of descriptor // build errors can be guaranteed for a pool. diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index c4e26b6c8c..e3eba97fcd 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -157,7 +157,6 @@ static void InitDefaultsscc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_ new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -177,7 +176,6 @@ static void InitDefaultsscc_info_DescriptorProto_ExtensionRange_google_2fprotobu new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -192,7 +190,6 @@ static void InitDefaultsscc_info_DescriptorProto_ReservedRange_google_2fprotobuf new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -206,7 +203,6 @@ static void InitDefaultsscc_info_EnumDescriptorProto_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -223,7 +219,6 @@ static void InitDefaultsscc_info_EnumDescriptorProto_EnumReservedRange_google_2f new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -237,7 +232,6 @@ static void InitDefaultsscc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2epr new (ptr) PROTOBUF_NAMESPACE_ID::EnumOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -252,7 +246,6 @@ static void InitDefaultsscc_info_EnumValueDescriptorProto_google_2fprotobuf_2fde new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -267,7 +260,6 @@ static void InitDefaultsscc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValueOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -282,7 +274,6 @@ static void InitDefaultsscc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescr new (ptr) PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -297,7 +288,6 @@ static void InitDefaultsscc_info_FieldDescriptorProto_google_2fprotobuf_2fdescri new (ptr) PROTOBUF_NAMESPACE_ID::FieldDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -312,7 +302,6 @@ static void InitDefaultsscc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2ep new (ptr) PROTOBUF_NAMESPACE_ID::FieldOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -327,7 +316,6 @@ static void InitDefaultsscc_info_FileDescriptorProto_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -347,7 +335,6 @@ static void InitDefaultsscc_info_FileDescriptorSet_google_2fprotobuf_2fdescripto new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorSet(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileDescriptorSet::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto = @@ -362,7 +349,6 @@ static void InitDefaultsscc_info_FileOptions_google_2fprotobuf_2fdescriptor_2epr new (ptr) PROTOBUF_NAMESPACE_ID::FileOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -377,7 +363,6 @@ static void InitDefaultsscc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescripto new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto = @@ -392,7 +377,6 @@ static void InitDefaultsscc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_ new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto = @@ -406,7 +390,6 @@ static void InitDefaultsscc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::MessageOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MessageOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -421,7 +404,6 @@ static void InitDefaultsscc_info_MethodDescriptorProto_google_2fprotobuf_2fdescr new (ptr) PROTOBUF_NAMESPACE_ID::MethodDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MethodDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -436,7 +418,6 @@ static void InitDefaultsscc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2e new (ptr) PROTOBUF_NAMESPACE_ID::MethodOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MethodOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -451,7 +432,6 @@ static void InitDefaultsscc_info_OneofDescriptorProto_google_2fprotobuf_2fdescri new (ptr) PROTOBUF_NAMESPACE_ID::OneofDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::OneofDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -466,7 +446,6 @@ static void InitDefaultsscc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2ep new (ptr) PROTOBUF_NAMESPACE_ID::OneofOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::OneofOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -481,7 +460,6 @@ static void InitDefaultsscc_info_ServiceDescriptorProto_google_2fprotobuf_2fdesc new (ptr) PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -497,7 +475,6 @@ static void InitDefaultsscc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::ServiceOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ServiceOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -512,7 +489,6 @@ static void InitDefaultsscc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceCodeInfo::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto = @@ -527,7 +503,6 @@ static void InitDefaultsscc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdes new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto = @@ -541,7 +516,6 @@ static void InitDefaultsscc_info_UninterpretedOption_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UninterpretedOption::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto = @@ -556,7 +530,6 @@ static void InitDefaultsscc_info_UninterpretedOption_NamePart_google_2fprotobuf_ new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto = @@ -1374,8 +1347,6 @@ constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE; // =================================================================== -void FileDescriptorSet::InitAsDefaultInstance() { -} class FileDescriptorSet::_Internal { public: }; @@ -1578,12 +1549,6 @@ void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { // =================================================================== -void FileDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FileOptions*>( - PROTOBUF_NAMESPACE_ID::FileOptions::internal_default_instance()); - PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceCodeInfo*>( - PROTOBUF_NAMESPACE_ID::SourceCodeInfo::internal_default_instance()); -} class FileDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2243,10 +2208,6 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { // =================================================================== -void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions*>( - PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::internal_default_instance()); -} class DescriptorProto_ExtensionRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2548,8 +2509,6 @@ void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange // =================================================================== -void DescriptorProto_ReservedRange::InitAsDefaultInstance() { -} class DescriptorProto_ReservedRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2804,10 +2763,6 @@ void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* // =================================================================== -void DescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MessageOptions*>( - PROTOBUF_NAMESPACE_ID::MessageOptions::internal_default_instance()); -} class DescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -3355,8 +3310,6 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { // =================================================================== -void ExtensionRangeOptions::InitAsDefaultInstance() { -} class ExtensionRangeOptions::_Internal { public: }; @@ -3580,10 +3533,6 @@ void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) { // =================================================================== -void FieldDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FieldOptions*>( - PROTOBUF_NAMESPACE_ID::FieldOptions::internal_default_instance()); -} class FieldDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4213,10 +4162,6 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { // =================================================================== -void OneofDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::OneofOptions*>( - PROTOBUF_NAMESPACE_ID::OneofOptions::internal_default_instance()); -} class OneofDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4495,8 +4440,6 @@ void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { // =================================================================== -void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() { -} class EnumDescriptorProto_EnumReservedRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4751,10 +4694,6 @@ void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_Enu // =================================================================== -void EnumDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumOptions*>( - PROTOBUF_NAMESPACE_ID::EnumOptions::internal_default_instance()); -} class EnumDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5137,10 +5076,6 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { // =================================================================== -void EnumValueDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumValueOptions*>( - PROTOBUF_NAMESPACE_ID::EnumValueOptions::internal_default_instance()); -} class EnumValueDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5456,10 +5391,6 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { // =================================================================== -void ServiceDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ServiceOptions*>( - PROTOBUF_NAMESPACE_ID::ServiceOptions::internal_default_instance()); -} class ServiceDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5771,10 +5702,6 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { // =================================================================== -void MethodDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MethodOptions*>( - PROTOBUF_NAMESPACE_ID::MethodOptions::internal_default_instance()); -} class MethodDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -6207,8 +6134,6 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { // =================================================================== -void FileOptions::InitAsDefaultInstance() { -} class FileOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -7194,8 +7119,6 @@ void FileOptions::InternalSwap(FileOptions* other) { // =================================================================== -void MessageOptions::InitAsDefaultInstance() { -} class MessageOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -7548,8 +7471,6 @@ void MessageOptions::InternalSwap(MessageOptions* other) { // =================================================================== -void FieldOptions::InitAsDefaultInstance() { -} class FieldOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -7967,8 +7888,6 @@ void FieldOptions::InternalSwap(FieldOptions* other) { // =================================================================== -void OneofOptions::InitAsDefaultInstance() { -} class OneofOptions::_Internal { public: }; @@ -8192,8 +8111,6 @@ void OneofOptions::InternalSwap(OneofOptions* other) { // =================================================================== -void EnumOptions::InitAsDefaultInstance() { -} class EnumOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -8496,8 +8413,6 @@ void EnumOptions::InternalSwap(EnumOptions* other) { // =================================================================== -void EnumValueOptions::InitAsDefaultInstance() { -} class EnumValueOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -8758,8 +8673,6 @@ void EnumValueOptions::InternalSwap(EnumValueOptions* other) { // =================================================================== -void ServiceOptions::InitAsDefaultInstance() { -} class ServiceOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9020,8 +8933,6 @@ void ServiceOptions::InternalSwap(ServiceOptions* other) { // =================================================================== -void MethodOptions::InitAsDefaultInstance() { -} class MethodOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9333,8 +9244,6 @@ void MethodOptions::InternalSwap(MethodOptions* other) { // =================================================================== -void UninterpretedOption_NamePart::InitAsDefaultInstance() { -} class UninterpretedOption_NamePart::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9612,8 +9521,6 @@ void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* ot // =================================================================== -void UninterpretedOption::InitAsDefaultInstance() { -} class UninterpretedOption::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -10057,8 +9964,6 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { // =================================================================== -void SourceCodeInfo_Location::InitAsDefaultInstance() { -} class SourceCodeInfo_Location::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -10451,8 +10356,6 @@ void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { // =================================================================== -void SourceCodeInfo::InitAsDefaultInstance() { -} class SourceCodeInfo::_Internal { public: }; @@ -10654,8 +10557,6 @@ void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { // =================================================================== -void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() { -} class GeneratedCodeInfo_Annotation::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -10995,8 +10896,6 @@ void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* ot // =================================================================== -void GeneratedCodeInfo::InitAsDefaultInstance() { -} class GeneratedCodeInfo::_Internal { public: }; diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index b10c78b006..21e9b90ab9 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -373,7 +373,6 @@ class PROTOBUF_EXPORT FileDescriptorSet PROTOBUF_FINAL : } static const FileDescriptorSet& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileDescriptorSet* internal_default_instance() { return reinterpret_cast( &_FileDescriptorSet_default_instance_); @@ -526,7 +525,6 @@ class PROTOBUF_EXPORT FileDescriptorProto PROTOBUF_FINAL : } static const FileDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileDescriptorProto* internal_default_instance() { return reinterpret_cast( &_FileDescriptorProto_default_instance_); @@ -920,7 +918,6 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange PROTOBUF_FINAL : } static const DescriptorProto_ExtensionRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto_ExtensionRange* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_ExtensionRange_default_instance_); @@ -1104,7 +1101,6 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange PROTOBUF_FINAL : } static const DescriptorProto_ReservedRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto_ReservedRange* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_ReservedRange_default_instance_); @@ -1268,7 +1264,6 @@ class PROTOBUF_EXPORT DescriptorProto PROTOBUF_FINAL : } static const DescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_default_instance_); @@ -1613,7 +1608,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions PROTOBUF_FINAL : } static const ExtensionRangeOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ExtensionRangeOptions* internal_default_instance() { return reinterpret_cast( &_ExtensionRangeOptions_default_instance_); @@ -1769,7 +1763,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto PROTOBUF_FINAL : } static const FieldDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldDescriptorProto* internal_default_instance() { return reinterpret_cast( &_FieldDescriptorProto_default_instance_); @@ -2202,7 +2195,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto PROTOBUF_FINAL : } static const OneofDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const OneofDescriptorProto* internal_default_instance() { return reinterpret_cast( &_OneofDescriptorProto_default_instance_); @@ -2378,7 +2370,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange PROTOBUF_FINAL : } static const EnumDescriptorProto_EnumReservedRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() { return reinterpret_cast( &_EnumDescriptorProto_EnumReservedRange_default_instance_); @@ -2542,7 +2533,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto PROTOBUF_FINAL : } static const EnumDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumDescriptorProto* internal_default_instance() { return reinterpret_cast( &_EnumDescriptorProto_default_instance_); @@ -2786,7 +2776,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto PROTOBUF_FINAL : } static const EnumValueDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValueDescriptorProto* internal_default_instance() { return reinterpret_cast( &_EnumValueDescriptorProto_default_instance_); @@ -2977,7 +2966,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto PROTOBUF_FINAL : } static const ServiceDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ServiceDescriptorProto* internal_default_instance() { return reinterpret_cast( &_ServiceDescriptorProto_default_instance_); @@ -3173,7 +3161,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto PROTOBUF_FINAL : } static const MethodDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MethodDescriptorProto* internal_default_instance() { return reinterpret_cast( &_MethodDescriptorProto_default_instance_); @@ -3423,7 +3410,6 @@ class PROTOBUF_EXPORT FileOptions PROTOBUF_FINAL : } static const FileOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileOptions* internal_default_instance() { return reinterpret_cast( &_FileOptions_default_instance_); @@ -3982,7 +3968,6 @@ class PROTOBUF_EXPORT MessageOptions PROTOBUF_FINAL : } static const MessageOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MessageOptions* internal_default_instance() { return reinterpret_cast( &_MessageOptions_default_instance_); @@ -4199,7 +4184,6 @@ class PROTOBUF_EXPORT FieldOptions PROTOBUF_FINAL : } static const FieldOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldOptions* internal_default_instance() { return reinterpret_cast( &_FieldOptions_default_instance_); @@ -4510,7 +4494,6 @@ class PROTOBUF_EXPORT OneofOptions PROTOBUF_FINAL : } static const OneofOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const OneofOptions* internal_default_instance() { return reinterpret_cast( &_OneofOptions_default_instance_); @@ -4666,7 +4649,6 @@ class PROTOBUF_EXPORT EnumOptions PROTOBUF_FINAL : } static const EnumOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumOptions* internal_default_instance() { return reinterpret_cast( &_EnumOptions_default_instance_); @@ -4853,7 +4835,6 @@ class PROTOBUF_EXPORT EnumValueOptions PROTOBUF_FINAL : } static const EnumValueOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValueOptions* internal_default_instance() { return reinterpret_cast( &_EnumValueOptions_default_instance_); @@ -5025,7 +5006,6 @@ class PROTOBUF_EXPORT ServiceOptions PROTOBUF_FINAL : } static const ServiceOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ServiceOptions* internal_default_instance() { return reinterpret_cast( &_ServiceOptions_default_instance_); @@ -5197,7 +5177,6 @@ class PROTOBUF_EXPORT MethodOptions PROTOBUF_FINAL : } static const MethodOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MethodOptions* internal_default_instance() { return reinterpret_cast( &_MethodOptions_default_instance_); @@ -5416,7 +5395,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart PROTOBUF_FINAL : } static const UninterpretedOption_NamePart& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UninterpretedOption_NamePart* internal_default_instance() { return reinterpret_cast( &_UninterpretedOption_NamePart_default_instance_); @@ -5590,7 +5568,6 @@ class PROTOBUF_EXPORT UninterpretedOption PROTOBUF_FINAL : } static const UninterpretedOption& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UninterpretedOption* internal_default_instance() { return reinterpret_cast( &_UninterpretedOption_default_instance_); @@ -5857,7 +5834,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location PROTOBUF_FINAL : } static const SourceCodeInfo_Location& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceCodeInfo_Location* internal_default_instance() { return reinterpret_cast( &_SourceCodeInfo_Location_default_instance_); @@ -6111,7 +6087,6 @@ class PROTOBUF_EXPORT SourceCodeInfo PROTOBUF_FINAL : } static const SourceCodeInfo& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceCodeInfo* internal_default_instance() { return reinterpret_cast( &_SourceCodeInfo_default_instance_); @@ -6266,7 +6241,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation PROTOBUF_FINAL : } static const GeneratedCodeInfo_Annotation& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const GeneratedCodeInfo_Annotation* internal_default_instance() { return reinterpret_cast( &_GeneratedCodeInfo_Annotation_default_instance_); @@ -6477,7 +6451,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo PROTOBUF_FINAL : } static const GeneratedCodeInfo& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const GeneratedCodeInfo* internal_default_instance() { return reinterpret_cast( &_GeneratedCodeInfo_default_instance_); @@ -7128,8 +7101,8 @@ inline void FileDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::FileOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) @@ -7211,8 +7184,8 @@ inline void FileDescriptorProto::clear_source_code_info() { } inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const { const PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = source_code_info_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const { // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) @@ -7428,8 +7401,8 @@ inline void DescriptorProto_ExtensionRange::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const { const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const { // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options) @@ -7883,8 +7856,8 @@ inline void DescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::MessageOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) @@ -8610,8 +8583,8 @@ inline void FieldDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::FieldOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) @@ -8799,8 +8772,8 @@ inline void OneofDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::OneofOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) @@ -9059,8 +9032,8 @@ inline void EnumDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::EnumOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) @@ -9361,8 +9334,8 @@ inline void EnumValueDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) @@ -9561,8 +9534,8 @@ inline void ServiceDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::ServiceOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) @@ -9870,8 +9843,8 @@ inline void MethodDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::MethodOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 6085a122a8..6da6ba7a32 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index b8bceca6c6..2284cdc5f0 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_Duration_google_2fprotobuf_2fduration_2eproto() new (ptr) PROTOBUF_NAMESPACE_ID::Duration(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Duration::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Duration_google_2fprotobuf_2fduration_2eproto = @@ -82,8 +81,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Duration::InitAsDefaultInstance() { -} class Duration::_Internal { public: }; diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index a530f51544..60f4ee1dfd 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT Duration PROTOBUF_FINAL : } static const Duration& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Duration* internal_default_instance() { return reinterpret_cast( &_Duration_default_instance_); diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 2af5109701..3d9adc200b 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -292,6 +292,13 @@ class DynamicMessage : public Message { ~DynamicMessage(); // Called on the prototype after construction to initialize message fields. + // Cross linking the default instances allows for fast reflection access of + // unset message fields. Without it we would have to go to the MessageFactory + // to get the prototype, which is a much more expensive operation. + // + // Generated messages do not cross-link to avoid dynamic initialization of the + // global instances. + // Instead, they keep the default instances in the FieldDescriptor objects. void CrossLinkPrototypes(); // implements Message ---------------------------------------------- diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 27f801fd9d..f30f2c97d2 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_Empty_google_2fprotobuf_2fempty_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Empty(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Empty::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Empty_google_2fprotobuf_2fempty_2eproto = @@ -79,8 +78,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Empty::InitAsDefaultInstance() { -} class Empty::_Internal { public: }; diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 17fda949f4..c87709afa1 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT Empty PROTOBUF_FINAL : } static const Empty& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Empty* internal_default_instance() { return reinterpret_cast( &_Empty_default_instance_); diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 3b1441e665..0dcabb0f47 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -1870,28 +1870,32 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { return; } - const auto old_flat_capacity = flat_capacity_; - + auto new_flat_capacity = flat_capacity_; do { - flat_capacity_ = flat_capacity_ == 0 ? 1 : flat_capacity_ * 4; - } while (flat_capacity_ < minimum_new_capacity); + new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4; + } while (new_flat_capacity < minimum_new_capacity); const KeyValue* begin = flat_begin(); const KeyValue* end = flat_end(); - if (flat_capacity_ > kMaximumFlatCapacity) { - // Switch to LargeMap - map_.large = Arena::Create(arena_); - LargeMap::iterator hint = map_.large->begin(); + AllocatedData new_map; + if (new_flat_capacity > kMaximumFlatCapacity) { + new_map.large = Arena::Create(arena_); + LargeMap::iterator hint = new_map.large->begin(); for (const KeyValue* it = begin; it != end; ++it) { - hint = map_.large->insert(hint, {it->first, it->second}); + hint = new_map.large->insert(hint, {it->first, it->second}); } - flat_size_ = 0; } else { - map_.flat = Arena::CreateArray(arena_, flat_capacity_); - std::copy(begin, end, map_.flat); + new_map.flat = Arena::CreateArray(arena_, new_flat_capacity); + std::copy(begin, end, new_map.flat); } + if (arena_ == nullptr) { - DeleteFlatMap(begin, old_flat_capacity); + DeleteFlatMap(begin, flat_capacity_); + } + flat_capacity_ = new_flat_capacity; + map_ = new_map; + if (is_large()) { + flat_size_ = 0; } } diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index e735b3ac66..4389093b6b 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2epr new (ptr) PROTOBUF_NAMESPACE_ID::FieldMask(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldMask::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto = @@ -81,8 +80,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void FieldMask::InitAsDefaultInstance() { -} class FieldMask::_Internal { public: }; diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index a493466136..cbea34b9a8 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT FieldMask PROTOBUF_FINAL : } static const FieldMask& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldMask* internal_default_instance() { return reinterpret_cast( &_FieldMask_default_instance_); diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index d8397ed258..0db7dfc0e8 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -320,15 +320,16 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { break; } - // Initially, the string points to the default value stored - // in the prototype. Only count the string if it has been - // changed from the default value. - const std::string* default_ptr = - &DefaultRaw(field).Get(); const std::string* ptr = &GetField(message, field).Get(); - if (ptr != default_ptr) { + // Initially, the string points to the default value stored + // in the prototype. Only count the string if it has been + // changed from the default value. + // Except oneof fields, those never point to a default instance, + // and there is no default instance to point to. + if (schema_.InRealOneof(field) || + ptr != &DefaultRaw(field).Get()) { // string fields are represented by just a pointer, so also // include sizeof(string) as well. total_size += @@ -359,8 +360,6 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { void Reflection::SwapField(Message* message1, Message* message2, const FieldDescriptor* field) const { - CheckInvalidAccess(schema_, field); - if (field->is_repeated()) { switch (field->cpp_type()) { #define SWAP_ARRAYS(CPPTYPE, TYPE) \ @@ -1121,6 +1120,8 @@ void Reflection::ListFieldsOmitStripped( if (field->is_extension()) { \ return GetExtensionSet(message).Get##TYPENAME( \ field->number(), field->default_value_##PASSTYPE()); \ + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \ + return field->default_value_##PASSTYPE(); \ } else { \ return GetField(message, field); \ } \ @@ -1190,6 +1191,9 @@ std::string Reflection::GetString(const Message& message, return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { @@ -1211,6 +1215,9 @@ const std::string& Reflection::GetStringReference(const Message& message, return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { @@ -1241,16 +1248,21 @@ void Reflection::SetString(Message* message, const FieldDescriptor* field, break; } + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it work. + // This allows us to not have the real default accessible from + // reflection. const std::string* default_ptr = - &DefaultRaw(field).Get(); + schema_.InRealOneof(field) + ? &GetEmptyString() + : &DefaultRaw(field).Get(); if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); MutableField(message, field) ->UnsafeSetDefault(default_ptr); } MutableField(message, field) - ->Mutable(default_ptr, GetArena(message)) - ->assign(std::move(value)); + ->Set(default_ptr, std::move(value), GetArena(message)); break; } } @@ -1342,6 +1354,8 @@ int Reflection::GetEnumValue(const Message& message, if (field->is_extension()) { value = GetExtensionSet(message).GetEnum( field->number(), field->default_value_enum()->number()); + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + value = field->default_value_enum()->number(); } else { value = GetField(message, field); } @@ -1476,6 +1490,40 @@ void Reflection::AddEnumValueInternal(Message* message, // ------------------------------------------------------------------- +const Message* Reflection::GetDefaultMessageInstance( + const FieldDescriptor* field) const { + // If we are using the generated factory, we cache the prototype in the field + // descriptor for faster access. + // The default instances of generated messages are not cross-linked, which + // means they contain null pointers on their message fields and can't be used + // to get the default of submessages. + if (message_factory_ == MessageFactory::generated_factory()) { + auto& ptr = field->default_generated_instance_; + auto* res = ptr.load(std::memory_order_acquire); + if (res == nullptr) { + // First time asking for this field's default. Load it and cache it. + res = message_factory_->GetPrototype(field->message_type()); + ptr.store(res, std::memory_order_release); + } + return res; + } + + // For other factories, we try the default's object field. + // In particular, the DynamicMessageFactory will cross link the default + // instances to allow for this. But only do this for real fields. + // This is an optimization to avoid going to GetPrototype() below, as that + // requires a lock and a map lookup. + if (!field->is_extension() && !field->options().weak() && + !field->options().lazy() && !schema_.InRealOneof(field)) { + auto* res = DefaultRaw(field); + if (res != nullptr) { + return res; + } + } + // Otherwise, just go to the factory. + return message_factory_->GetPrototype(field->message_type()); +} + const Message& Reflection::GetMessage(const Message& message, const FieldDescriptor* field, MessageFactory* factory) const { @@ -1488,9 +1536,12 @@ const Message& Reflection::GetMessage(const Message& message, return static_cast(GetExtensionSet(message).GetMessage( field->number(), field->message_type(), factory)); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return *GetDefaultMessageInstance(field); + } const Message* result = GetRaw(message, field); if (result == nullptr) { - result = DefaultRaw(field); + result = GetDefaultMessageInstance(field); } return *result; } @@ -1516,7 +1567,7 @@ Message* Reflection::MutableMessage(Message* message, if (!HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); result_holder = MutableField(message, field); - const Message* default_message = DefaultRaw(field); + const Message* default_message = GetDefaultMessageInstance(field); *result_holder = default_message->New(message->GetArena()); } } else { @@ -1524,7 +1575,7 @@ Message* Reflection::MutableMessage(Message* message, } if (*result_holder == nullptr) { - const Message* default_message = DefaultRaw(field); + const Message* default_message = GetDefaultMessageInstance(field); *result_holder = default_message->New(message->GetArena()); } result = *result_holder; @@ -1903,9 +1954,8 @@ Type* Reflection::MutableRawNonOneof(Message* message, template const Type& Reflection::GetRaw(const Message& message, const FieldDescriptor* field) const { - if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { - return DefaultRaw(field); - } + GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) + << "Field = " << field->full_name(); return GetConstRefAtOffset(message, schema_.GetFieldOffset(field)); } @@ -2112,8 +2162,11 @@ void Reflection::ClearOneof(Message* message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - const std::string* default_ptr = - &DefaultRaw(field).Get(); + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it + // work. This allows us to not have the real default accessible + // from reflection. + const std::string* default_ptr = &GetEmptyString(); MutableField(message, field) ->Destroy(default_ptr, GetArena(message)); break; diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index cb2ae35e04..1c284959d0 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -212,6 +212,12 @@ struct ReflectionSchema { OffsetValue(offsets_[field->index()], field->type()); } + // Returns true if the field's accessor is called by any external code (aka, + // non proto library code). + bool IsFieldUsed(const FieldDescriptor* field) const { + return true; + } + bool IsFieldStripped(const FieldDescriptor* field) const { return false; } @@ -242,6 +248,7 @@ struct ReflectionSchema { // We tag offset values to provide additional data about fields (such as // inlined). static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) { + v &= 0x7FFFFFFFu; if (type == FieldDescriptor::TYPE_STRING || type == FieldDescriptor::TYPE_BYTES) { return v & ~1u; @@ -296,6 +303,13 @@ struct PROTOBUF_EXPORT DescriptorTable { const ServiceDescriptor** file_level_service_descriptors; }; +enum { + // Tag used on offsets for fields that don't have a real offset. + // For example, weak message fields go into the WeakFieldMap and not in an + // actual field. + kInvalidFieldOffsetTag = 0x40000000u, +}; + // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool // and uses it to populate all of the global variables which store pointers to // the descriptor objects. It also constructs the reflection objects. It is diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc index 1c9d408db1..7234f5f932 100644 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ b/src/google/protobuf/generated_message_reflection_unittest.cc @@ -486,6 +486,7 @@ TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { ->FindKnownExtensionByName(extension1->full_name()) == NULL); } + TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) { unittest::TestAllTypes from_message1; unittest::TestAllTypes from_message2; diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index b23a86d4f6..6e5cdebbf1 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -48,7 +48,6 @@ #include #include - #include namespace google { diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 51cda2a88e..34bf45ff70 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -140,29 +140,25 @@ StringOutputStream::StringOutputStream(std::string* target) : target_(target) {} bool StringOutputStream::Next(void** data, int* size) { GOOGLE_CHECK(target_ != NULL); - int old_size = target_->size(); + size_t old_size = target_->size(); // Grow the string. + size_t new_size; if (old_size < target_->capacity()) { // Resize the string to match its capacity, since we can get away // without a memory allocation this way. - STLStringResizeUninitialized(target_, target_->capacity()); + new_size = target_->capacity(); } else { - // Size has reached capacity, try to double the size. - if (old_size > std::numeric_limits::max() / 2) { - // Can not double the size otherwise it is going to cause integer - // overflow in the expression below: old_size * 2 "; - GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for " - << "StringOutputStream."; - return false; - } - // Double the size, also make sure that the new size is at least - // kMinimumSize. - STLStringResizeUninitialized( - target_, - std::max(old_size * 2, - kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. + // Size has reached capacity, try to double it. + new_size = old_size * 2; } + // Avoid integer overflow in returned '*size'. + new_size = std::min(new_size, old_size + std::numeric_limits::max()); + // Increase the size, also make sure that it is at least kMinimumSize. + STLStringResizeUninitialized( + target_, + std::max(new_size, + kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. *data = mutable_string_data(target_) + old_size; *size = target_->size() - old_size; diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 26572cc55c..2f0c662274 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -150,7 +150,7 @@ class PROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { int64_t ByteCount() const override; private: - static const int kMinimumSize = 16; + static constexpr size_t kMinimumSize = 16; std::string* target_; diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index bec9df0af6..b0f84fb913 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -712,6 +712,21 @@ TEST_F(IoTest, StringIo) { } } +// Verifies that outputs up to kint32max can be created. +TEST_F(IoTest, LargeOutput) { + std::string str; + StringOutputStream output(&str); + void* unused_data; + int size; + // Repeatedly calling Next should eventually grow the buffer to kint32max. + do { + EXPECT_TRUE(output.Next(&unused_data, &size)); + } while (str.size() < std::numeric_limits::max()); + // Further increases should be possible. + output.Next(&unused_data, &size); + EXPECT_GT(size, 0); +} + // To test files, we create a temporary file, write, read, truncate, repeat. TEST_F(IoTest, FileIo) { diff --git a/src/google/protobuf/map.cc b/src/google/protobuf/map.cc new file mode 100644 index 0000000000..d60a9a285c --- /dev/null +++ b/src/google/protobuf/map.cc @@ -0,0 +1,41 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +namespace google { +namespace protobuf { +namespace internal { + +void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr}; + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index c3cfb4318a..c25f334673 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -182,7 +182,7 @@ class MapAllocator { private: using DestructorSkippable_ = void; - Arena* const arena_; + Arena* arena_; }; template @@ -280,6 +280,9 @@ size_t MapValueSpaceUsedExcludingSelfLong(const T& message) { return message.SpaceUsedLong() - sizeof(T); } +constexpr size_t kGlobalEmptyTableSize = 1; +PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize]; + // Space used for the table, trees, and nodes. // Does not include the indirect space used. Eg the data of a std::string. template @@ -377,24 +380,22 @@ class Map { using size_type = size_t; using hasher = typename internal::TransparentSupport::hash; - Map() : arena_(nullptr) { Init(); } - explicit Map(Arena* arena) : arena_(arena) { Init(); } + Map() : elements_(nullptr) {} + explicit Map(Arena* arena) : elements_(arena) {} - Map(const Map& other) : arena_(nullptr) { - Init(); - insert(other.begin(), other.end()); - } + Map(const Map& other) : Map() { insert(other.begin(), other.end()); } Map(Map&& other) noexcept : Map() { - if (other.arena_) { + if (other.arena() != nullptr) { *this = other; } else { swap(other); } } + Map& operator=(Map&& other) noexcept { if (this != &other) { - if (arena_ != other.arena_) { + if (arena() != other.arena()) { *this = other; } else { swap(other); @@ -404,21 +405,13 @@ class Map { } template - Map(const InputIt& first, const InputIt& last) : arena_(nullptr) { - Init(); + Map(const InputIt& first, const InputIt& last) : Map() { insert(first, last); } - ~Map() { - if (arena_ == nullptr) { - clear(); - delete elements_; - } - } + ~Map() {} private: - void Init() { elements_ = Arena::CreateMessage(arena_, 0); } - using Allocator = internal::MapAllocator; // InnerMap is a generic hash-based map. It doesn't contain any @@ -455,20 +448,18 @@ class Map { // otherwise. This avoids unncessary copies of string keys, for example. class InnerMap : private hasher { public: - explicit InnerMap(size_type n) : InnerMap(nullptr, n) {} - InnerMap(Arena* arena, size_type n) + explicit InnerMap(Arena* arena) : hasher(), num_elements_(0), + num_buckets_(internal::kGlobalEmptyTableSize), seed_(Seed()), - table_(nullptr), - alloc_(arena) { - n = TableSize(n); - table_ = CreateEmptyTable(n); - num_buckets_ = index_of_first_non_null_ = n; - } + index_of_first_non_null_(num_buckets_), + table_(const_cast(internal::kGlobalEmptyTable)), + alloc_(arena) {} ~InnerMap() { - if (table_ != nullptr) { + if (alloc_.arena() == nullptr && + num_buckets_ != internal::kGlobalEmptyTableSize) { clear(); Dealloc(table_, num_buckets_); } @@ -627,6 +618,17 @@ class Map { using iterator = iterator_base; using const_iterator = iterator_base; + Arena* arena() const { return alloc_.arena(); } + + void Swap(InnerMap* other) { + std::swap(num_elements_, other->num_elements_); + std::swap(num_buckets_, other->num_buckets_); + std::swap(seed_, other->seed_); + std::swap(index_of_first_non_null_, other->index_of_first_non_null_); + std::swap(table_, other->table_); + std::swap(alloc_, other->alloc_); + } + iterator begin() { return iterator(this); } iterator end() { return iterator(); } const_iterator begin() const { return const_iterator(this); } @@ -676,6 +678,11 @@ class Map { return iterator(FindHelper(k).first); } + template + const_iterator find(const K& k) const { + return FindHelper(k).first; + } + // Insert the key into the map, if not present. In that case, the value will // be value initialized. std::pair insert(const Key& k) { @@ -895,6 +902,14 @@ class Map { // Resize to the given number of buckets. void Resize(size_t new_num_buckets) { + if (num_buckets_ == internal::kGlobalEmptyTableSize) { + // This is the global empty array. + // Just overwrite with a new one. No need to transfer or free anything. + num_buckets_ = index_of_first_non_null_ = kMinTableSize; + table_ = CreateEmptyTable(num_buckets_); + return; + } + GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize); void** const old_table = table_; const size_type old_table_size = num_buckets_; @@ -1057,7 +1072,7 @@ class Map { #if defined(__x86_64__) && defined(__GNUC__) && \ !defined(GOOGLE_PROTOBUF_NO_RDTSC) uint32 hi, lo; - asm("rdtsc" : "=a"(lo), "=d"(hi)); + asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); s += ((static_cast(hi) << 32) | lo); #endif return s; @@ -1155,23 +1170,19 @@ class Map { InnerIt it_; }; - iterator begin() { return iterator(elements_->begin()); } - iterator end() { return iterator(elements_->end()); } - const_iterator begin() const { - return const_iterator(iterator(elements_->begin())); - } - const_iterator end() const { - return const_iterator(iterator(elements_->end())); - } + iterator begin() { return iterator(elements_.begin()); } + iterator end() { return iterator(elements_.end()); } + const_iterator begin() const { return const_iterator(elements_.begin()); } + const_iterator end() const { return const_iterator(elements_.end()); } const_iterator cbegin() const { return begin(); } const_iterator cend() const { return end(); } // Capacity - size_type size() const { return elements_->size(); } + size_type size() const { return elements_.size(); } bool empty() const { return size() == 0; } // Element access - T& operator[](const key_type& key) { return (*elements_)[key].second; } + T& operator[](const key_type& key) { return elements_[key].second; } template const T& at(const key_arg& key) const { @@ -1195,11 +1206,11 @@ class Map { template const_iterator find(const key_arg& key) const { - return const_iterator(iterator(elements_->find(key))); + return const_iterator(elements_.find(key)); } template iterator find(const key_arg& key) { - return iterator(elements_->find(key)); + return iterator(elements_.find(key)); } template @@ -1233,7 +1244,7 @@ class Map { // insert std::pair insert(const value_type& value) { std::pair p = - elements_->insert(value.first); + elements_.insert(value.first); if (p.second) { p.first->second = value.second; } @@ -1265,7 +1276,7 @@ class Map { } iterator erase(iterator pos) { iterator i = pos++; - elements_->erase(i.it_); + elements_.erase(i.it_); return pos; } void erase(iterator first, iterator last) { @@ -1273,7 +1284,7 @@ class Map { first = erase(first); } } - void clear() { elements_->clear(); } + void clear() { elements_.clear(); } // Assign Map& operator=(const Map& other) { @@ -1285,8 +1296,8 @@ class Map { } void swap(Map& other) { - if (arena_ == other.arena_) { - std::swap(elements_, other.elements_); + if (arena() == other.arena()) { + elements_.Swap(&other.elements_); } else { // TODO(zuguang): optimize this. The temporary copy can be allocated // in the same arena as the other message, and the "other = copy" can @@ -1299,16 +1310,16 @@ class Map { // Access to hasher. Currently this returns a copy, but it may // be modified to return a const reference in the future. - hasher hash_function() const { return elements_->hash_function(); } + hasher hash_function() const { return elements_.hash_function(); } size_t SpaceUsedExcludingSelfLong() const { - return sizeof(InnerMap) + elements_->SpaceUsedInternal() + - internal::SpaceUsedInValues(this); + if (empty()) return 0; + return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this); } private: - Arena* arena_; - InnerMap* elements_; + Arena* arena() const { return elements_.arena(); } + InnerMap elements_; friend class Arena; using InternalArenaConstructable_ = void; diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 6b5d4e8fdf..92cb4ac4d1 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -206,8 +206,7 @@ class MapEntryImpl : public Base { return KeyTypeHandler::GetExternalReference(key_); } virtual inline const ValueMapEntryAccessorType& value() const { - return ValueTypeHandler::DefaultIfNotInitialized( - value_, Derived::internal_default_instance()->value_); + return ValueTypeHandler::DefaultIfNotInitialized(value_); } inline KeyMapEntryAccessorType* mutable_key() { set_has_key(); @@ -323,12 +322,6 @@ class MapEntryImpl : public Base { clear_has_value(); } - static void InitAsDefaultInstance() { - Derived* d = const_cast(Derived::internal_default_instance()); - KeyTypeHandler::AssignDefaultValue(&d->key_); - ValueTypeHandler::AssignDefaultValue(&d->value_); - } - // Parsing using MergePartialFromCodedStream, above, is not as // efficient as it could be. This helper class provides a speedier way. template diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index efca5ee83c..6a28b6ec07 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -264,6 +264,53 @@ class PROTOBUF_EXPORT MapKey { int type_; }; +} // namespace protobuf +} // namespace google +namespace std { +template <> +struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> { + size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const { + switch (map_key.type()) { + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING: + return hash()(map_key.GetStringValue()); + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: { + auto value = map_key.GetInt64Value(); + return hash()(value); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: { + auto value = map_key.GetInt32Value(); + return hash()(map_key.GetInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: { + auto value = map_key.GetUInt64Value(); + return hash()(map_key.GetUInt64Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: { + auto value = map_key.GetUInt32Value(); + return hash()(map_key.GetUInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: { + return hash()(map_key.GetBoolValue()); + } + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } + bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1, + const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const { + return map_key1 < map_key2; + } +}; +} // namespace std + +namespace google { +namespace protobuf { namespace internal { class ContendedMapCleanTest; @@ -791,48 +838,6 @@ class PROTOBUF_EXPORT MapIterator { } // namespace protobuf } // namespace google -namespace std { -template <> -struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> { - size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const { - switch (map_key.type()) { - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING: - return hash()(map_key.GetStringValue()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: { - auto value = map_key.GetInt64Value(); - return hash()(value); - } - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: { - auto value = map_key.GetInt32Value(); - return hash()(map_key.GetInt32Value()); - } - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: { - auto value = map_key.GetUInt64Value(); - return hash()(map_key.GetUInt64Value()); - } - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: { - auto value = map_key.GetUInt32Value(); - return hash()(map_key.GetUInt32Value()); - } - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: { - return hash()(map_key.GetBoolValue()); - } - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; - } - bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1, - const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const { - return map_key1 < map_key2; - } -}; -} // namespace std #include #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index db0ddc9446..240903be9c 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -85,7 +85,7 @@ class MapFieldLite { // Used in the implementation of parsing. Caller should take the ownership iff // arena_ is NULL. EntryType* NewEntry() const { - return Arena::CreateMessage(map_.arena_); + return Arena::CreateMessage(map_.arena()); } // Used in the implementation of serializing enum value type. Caller should // take the ownership iff arena_ is NULL. diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 9256f0e97f..3eb46a0f57 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -982,13 +982,10 @@ TEST_F(MapImplTest, CopyAssignMapIterator) { TEST_F(MapImplTest, SpaceUsed) { constexpr size_t kMinCap = 8; - constexpr size_t kInnerMapOverhead = sizeof(size_t) * 4 + sizeof(void*) * 2; Map m; - // To check the current overhead of an empty map. - // Ideally this should be zero. - EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), - sizeof(void*) * kMinCap + kInnerMapOverhead); + // An newly constructed map should have no space used. + EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0); size_t capacity = kMinCap; for (int i = 0; i < 100; ++i) { @@ -998,7 +995,7 @@ TEST_F(MapImplTest, SpaceUsed) { capacity *= 2; } EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), - sizeof(void*) * capacity + kInnerMapOverhead + + sizeof(void*) * capacity + m.size() * sizeof(std::pair, void*>)); } @@ -1007,7 +1004,7 @@ TEST_F(MapImplTest, SpaceUsed) { std::string str = "Some arbitrarily large string"; m2[str] = 1; EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(), - sizeof(void*) * kMinCap + kInnerMapOverhead + + sizeof(void*) * kMinCap + sizeof(std::pair, void*>) + internal::StringSpaceUsedExcludingSelfLong(str)); @@ -1015,7 +1012,7 @@ TEST_F(MapImplTest, SpaceUsed) { Map m3; m3[0].set_optional_string(str); EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(), - sizeof(void*) * kMinCap + kInnerMapOverhead + + sizeof(void*) * kMinCap + sizeof(std::pair, void*>) + m3[0].SpaceUsedLong() - sizeof(m3[0])); } diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index aba35becc7..7908544286 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -163,12 +163,9 @@ class MapTypeHandler { // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding // those already calculate in sizeof(MapField). static inline size_t SpaceUsedInMapEntryLong(const Type* value); - // Assign default value to given instance. - static inline void AssignDefaultValue(Type** value); // Return default instance if value is not initialized when calling const // reference accessor. - static inline const Type& DefaultIfNotInitialized(const Type* value, - const Type* default_value); + static inline const Type& DefaultIfNotInitialized(const Type* value); // Check if all required fields have values set. static inline bool IsInitialized(Type* value); }; @@ -206,9 +203,8 @@ class MapTypeHandler { TypeOnMemory* to, Arena* arena); \ static inline void Clear(TypeOnMemory* value, Arena* arena); \ static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ - static inline void AssignDefaultValue(TypeOnMemory* value); \ static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ - const TypeOnMemory& value, const TypeOnMemory& default_value); \ + const TypeOnMemory& value); \ static inline bool IsInitialized(const TypeOnMemory& value); \ static void DeleteNoArena(TypeOnMemory& value); \ static inline void Initialize(TypeOnMemory* value, Arena* arena); \ @@ -525,12 +521,6 @@ void MapTypeHandler::DeleteNoArena( delete ptr; } -template -inline void MapTypeHandler::AssignDefaultValue(Type** value) { - *value = const_cast(Type::internal_default_instance()); -} - template inline void MapTypeHandler::Initialize( Type** x, Arena* /* arena */) { @@ -551,8 +541,8 @@ inline Type* MapTypeHandler::EnsureMutable( template inline const Type& MapTypeHandler::DefaultIfNotInitialized( - const Type* value, const Type* default_value) { - return value != NULL ? *value : *default_value; + const Type* value) { + return value != NULL ? *value : *Type::internal_default_instance(); } template @@ -594,10 +584,6 @@ inline bool MapTypeHandler::IsInitialized( } \ template \ inline void \ - MapTypeHandler::AssignDefaultValue( \ - TypeOnMemory* /* value */) {} \ - template \ - inline void \ MapTypeHandler::Initialize( \ TypeOnMemory* value, Arena* /* arena */) { \ value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \ @@ -612,9 +598,8 @@ inline bool MapTypeHandler::IsInitialized( template \ inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler:: \ - DefaultIfNotInitialized(const TypeOnMemory& value, \ - const TypeOnMemory& /* default_value */) { \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ return value.Get(); \ } \ template \ @@ -627,63 +612,58 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) #undef STRING_OR_BYTES_HANDLER_FUNCTIONS -#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ - return value; \ - } \ - template \ - inline size_t MapTypeHandler:: \ - SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \ - return 0; \ - } \ - template \ - inline void MapTypeHandler::Clear( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ - } \ - template \ - inline void MapTypeHandler::Merge( \ - const MapEntryAccessorType& from, TypeOnMemory* to, \ - Arena* /* arena */) { \ - *to = from; \ - } \ - template \ - inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ - template \ - inline void \ - MapTypeHandler::AssignDefaultValue( \ - TypeOnMemory* /* value */) {} \ - template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ - } \ - template \ - inline typename MapTypeHandler::MapEntryAccessorType* \ - MapTypeHandler::EnsureMutable( \ - TypeOnMemory* value, Arena* /* arena */) { \ - return value; \ - } \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler:: \ - DefaultIfNotInitialized(const TypeOnMemory& value, \ - const TypeOnMemory& /* default_value */) { \ - return value; \ - } \ - template \ - inline bool \ - MapTypeHandler::IsInitialized( \ - const TypeOnMemory& /* value */) { \ - return true; \ +#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ + return value; \ + } \ + template \ + inline size_t MapTypeHandler:: \ + SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \ + return 0; \ + } \ + template \ + inline void MapTypeHandler::Clear( \ + TypeOnMemory* value, Arena* /* arena */) { \ + *value = 0; \ + } \ + template \ + inline void MapTypeHandler::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, \ + Arena* /* arena */) { \ + *to = from; \ + } \ + template \ + inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ + template \ + inline void \ + MapTypeHandler::Initialize( \ + TypeOnMemory* value, Arena* /* arena */) { \ + *value = 0; \ + } \ + template \ + inline typename MapTypeHandler::MapEntryAccessorType* \ + MapTypeHandler::EnsureMutable( \ + TypeOnMemory* value, Arena* /* arena */) { \ + return value; \ + } \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ + return value; \ + } \ + template \ + inline bool \ + MapTypeHandler::IsInitialized( \ + const TypeOnMemory& /* value */) { \ + return true; \ } PRIMITIVE_HANDLER_FUNCTIONS(INT64) PRIMITIVE_HANDLER_FUNCTIONS(UINT64) diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index cfea396a4b..fde10cf617 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -162,6 +162,10 @@ size_t Message::SpaceUsedLong() const { return GetReflection()->SpaceUsedLong(*this); } +size_t Message::GetInvariantPerBuild(size_t salt) { + return salt; +} + // ============================================================================= // MessageFactory diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 24b48debd1..d0ca0366a5 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -170,6 +170,9 @@ class CelMapReflectionFriend; // field_backed_map_impl.cc namespace internal { class MapFieldPrinterHelper; // text_format.cc } +namespace util { +class MessageDifferencer; +} namespace internal { @@ -362,6 +365,9 @@ class PROTOBUF_EXPORT Message : public MessageLite { inline explicit Message(Arena* arena) : MessageLite(arena) {} + protected: + static size_t GetInvariantPerBuild(size_t salt); + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); }; @@ -945,6 +951,7 @@ class PROTOBUF_EXPORT Reflection final { friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper; friend class DynamicMessageFactory; friend class python::MapReflectionFriend; + friend class util::MessageDifferencer; #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND friend class expr::CelMapReflectionFriend; friend class internal::MapFieldReflectionTest; @@ -1020,6 +1027,8 @@ class PROTOBUF_EXPORT Reflection final { template const Type& DefaultRaw(const FieldDescriptor* field) const; + const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; + inline const uint32* GetHasBits(const Message& message) const; inline uint32* MutableHasBits(Message* message) const; inline uint32 GetOneofCase(const Message& message, diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 4b950439a1..1b0aa333a4 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -59,6 +58,7 @@ #include #include #include +#include #include diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 07800f5554..c1c4774685 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -334,13 +334,12 @@ class RepeatedField final { int total_size_; struct Rep { Arena* arena; - Element elements[1]; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + Element elements[(std::numeric_limits::max() - 2 * sizeof(Arena*)) / + sizeof(Element)]; }; - // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on - // the struct. We can not use sizeof(Arena*) as well because there might be - // a "gap" after the field arena and before the field elements (e.g., when - // Element is double and pointer is 32bit). - static const size_t kRepHeaderSize; + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); // If total_size_ == 0 this points to an Arena otherwise it points to the // elements member of a Rep struct. Using this invariant allows the storage of @@ -381,14 +380,14 @@ class RepeatedField final { void CopyArray(Element* to, const Element* from, int size); // Internal helper to delete all elements and deallocate the storage. - // If Element has a trivial destructor (for example, if it's a fundamental - // type, like int32), the loop will be removed by the optimizer. void InternalDeallocate(Rep* rep, int size) { if (rep != NULL) { Element* e = &rep->elements[0]; - Element* limit = &rep->elements[size]; - for (; e < limit; e++) { - e->~Element(); + if (!std::is_trivial::value) { + Element* limit = &rep->elements[size]; + for (; e < limit; e++) { + e->~Element(); + } } if (rep->arena == NULL) { #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) @@ -487,10 +486,6 @@ class RepeatedField final { friend class ::google::protobuf::internal::ParseContext; }; -template -const size_t RepeatedField::kRepHeaderSize = - reinterpret_cast(&reinterpret_cast(16)->elements[0]) - 16; - namespace internal { template class RepeatedPtrIterator; @@ -741,9 +736,12 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { int total_size_; struct Rep { int allocated_size; - void* elements[1]; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + void* elements[(std::numeric_limits::max() - 2 * sizeof(int)) / + sizeof(void*)]; }; - static constexpr size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*); + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); Rep* rep_; template diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 26b2384729..8de9504dc0 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -328,10 +328,18 @@ TEST(RepeatedField, ReserveHuge) { EXPECT_GE(huge_field.Capacity(), min_clamping_size); ASSERT_LT(huge_field.Capacity(), std::numeric_limits::max() - 1); +#ifndef ADDRESS_SANITIZER + // The array containing all the fields is, in theory, up to MAXINT-1 in size. + // However, some compilers can't handle a struct whose size is larger + // than 2GB, and the protocol buffer format doesn't handle more than 2GB of + // data at once, either. So we limit it, but the code below accesses beyond + // that limit. + // Allocation may return more memory than we requested. However, the updated // size must still be clamped to a valid range. huge_field.Reserve(huge_field.Capacity() + 1); EXPECT_EQ(huge_field.Capacity(), std::numeric_limits::max()); +#endif #endif // PROTOBUF_TEST_ALLOW_LARGE_ALLOC } diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 059456f287..925686972a 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_SourceContext_google_2fprotobuf_2fsource_5fcont new (ptr) PROTOBUF_NAMESPACE_ID::SourceContext(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceContext::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto = @@ -81,8 +80,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void SourceContext::InitAsDefaultInstance() { -} class SourceContext::_Internal { public: }; diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 6ebb809d8e..a565129e5f 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT SourceContext PROTOBUF_FINAL : } static const SourceContext& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceContext* internal_default_instance() { return reinterpret_cast( &_SourceContext_default_instance_); diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 54c928342b..d94b86d2c7 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -27,12 +27,6 @@ class StructDefaultTypeInternal { class ValueDefaultTypeInternal { public: ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; - int null_value_; - double number_value_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_; - bool bool_value_; - const PROTOBUF_NAMESPACE_ID::Struct* struct_value_; - const PROTOBUF_NAMESPACE_ID::ListValue* list_value_; } _Value_default_instance_; class ListValueDefaultTypeInternal { public: @@ -61,10 +55,6 @@ static void InitDefaultsscc_info_ListValue_google_2fprotobuf_2fstruct_2eproto() new (ptr) PROTOBUF_NAMESPACE_ID::ListValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::Struct::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::Value::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::ListValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto = @@ -95,12 +85,12 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fstruct_2ep ~0u, // no _extensions_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]), ~0u, // no _weak_field_map_ - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, null_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, number_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, string_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, bool_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, struct_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, list_value_), + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, kind_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_), @@ -190,8 +180,6 @@ void Struct_FieldsEntry_DoNotUse::MergeFrom( // =================================================================== -void Struct::InitAsDefaultInstance() { -} class Struct::_Internal { public: }; @@ -428,17 +416,6 @@ void Struct::InternalSwap(Struct* other) { // =================================================================== -void Value::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.null_value_ = 0; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.number_value_ = 0; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.string_value_.UnsafeSetDefault( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.bool_value_ = false; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.struct_value_ = const_cast< PROTOBUF_NAMESPACE_ID::Struct*>( - PROTOBUF_NAMESPACE_ID::Struct::internal_default_instance()); - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.list_value_ = const_cast< PROTOBUF_NAMESPACE_ID::ListValue*>( - PROTOBUF_NAMESPACE_ID::ListValue::internal_default_instance()); -} class Value::_Internal { public: static const PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg); @@ -885,8 +862,6 @@ void Value::InternalSwap(Value* other) { // =================================================================== -void ListValue::InitAsDefaultInstance() { -} class ListValue::_Internal { public: }; diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 772f1a4da0..b065bd2064 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -172,7 +172,6 @@ class PROTOBUF_EXPORT Struct PROTOBUF_FINAL : } static const Struct& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Struct* internal_default_instance() { return reinterpret_cast( &_Struct_default_instance_); @@ -332,7 +331,6 @@ class PROTOBUF_EXPORT Value PROTOBUF_FINAL : KIND_NOT_SET = 0, }; - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Value* internal_default_instance() { return reinterpret_cast( &_Value_default_instance_); @@ -577,7 +575,6 @@ class PROTOBUF_EXPORT ListValue PROTOBUF_FINAL : } static const ListValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ListValue* internal_default_instance() { return reinterpret_cast( &_ListValue_default_instance_); @@ -977,7 +974,7 @@ inline PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() { inline const PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const { return _internal_has_struct_value() ? *kind_.struct_value_ - : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct*>(&PROTOBUF_NAMESPACE_ID::_Struct_default_instance_); + : reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct&>(PROTOBUF_NAMESPACE_ID::_Struct_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) @@ -1050,7 +1047,7 @@ inline PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() { inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const { return _internal_has_list_value() ? *kind_.list_value_ - : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue*>(&PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_); + : reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue&>(PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 58ed5a4717..11e9b0001f 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -286,6 +286,15 @@ class TextFormat::Parser::ParserImpl { // Consume fields until we cannot do so anymore. while (true) { if (LookingAtType(io::Tokenizer::TYPE_END)) { + // Ensures recursion limit properly unwinded, but only for success + // cases. This implicitly avoids the check when `Parse` returns false + // via `DO(...)`. + GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_) + << "Recursion limit at end of parse should be " + << initial_recursion_limit_ << ", but was " << recursion_limit_ + << ". Difference of " << initial_recursion_limit_ - recursion_limit_ + << " stack frames not accounted for stack unwind."; + return !had_errors_; } @@ -832,10 +841,19 @@ class TextFormat::Parser::ParserImpl { } bool SkipFieldValue() { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { while (LookingAtType(io::Tokenizer::TYPE_STRING)) { tokenizer_.Next(); } + ++recursion_limit_; return true; } if (TryConsume("[")) { @@ -850,6 +868,7 @@ class TextFormat::Parser::ParserImpl { } DO(Consume(",")); } + ++recursion_limit_; return true; } // Possible field values other than string: @@ -879,6 +898,7 @@ class TextFormat::Parser::ParserImpl { !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { std::string text = tokenizer_.current().text; ReportError("Cannot skip field value, unexpected token: " + text); + ++recursion_limit_; return false; } // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field @@ -893,10 +913,12 @@ class TextFormat::Parser::ParserImpl { if (text != "inf" && text != "infinity" && text != "nan") { ReportError("Invalid float number: " + text); + ++recursion_limit_; return false; } } tokenizer_.Next(); + ++recursion_limit_; return true; } @@ -1432,7 +1454,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, return MergeUsingImpl(input, output, &parser); } -bool TextFormat::Parser::ParseFromString(const std::string& input, +bool TextFormat::Parser::ParseFromString(ConstStringParam input, Message* output) { DO(CheckParseInputSize(input, error_collector_)); io::ArrayInputStream input_stream(input.data(), input.size()); @@ -1497,7 +1519,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input, return Parser().Merge(input, output); } -/* static */ bool TextFormat::ParseFromString(const std::string& input, +/* static */ bool TextFormat::ParseFromString(ConstStringParam input, Message* output) { return Parser().ParseFromString(input, output); } @@ -1525,9 +1547,9 @@ class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { // Some compilers do not support ref-qualifiers even in C++11 mode. // Disable the optimization for now and revisit it later. -#if 0 // LANG_CXX11 +#if 0 // LANG_CXX11 std::string Consume() && { return std::move(output_); } -#else // !LANG_CXX11 +#else // !LANG_CXX11 const std::string& Get() { return output_; } #endif // LANG_CXX11 diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index 9eb2eebf08..e4b32557f4 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -454,7 +454,7 @@ class PROTOBUF_EXPORT TextFormat { // google::protobuf::MessageLite::ParseFromString(). static bool Parse(io::ZeroCopyInputStream* input, Message* output); // Like Parse(), but reads directly from a string. - static bool ParseFromString(const std::string& input, Message* output); + static bool ParseFromString(ConstStringParam input, Message* output); // Like Parse(), but the data is merged into the given message, as if // using Message::MergeFrom(). @@ -531,7 +531,7 @@ class PROTOBUF_EXPORT TextFormat { // Like TextFormat::Parse(). bool Parse(io::ZeroCopyInputStream* input, Message* output); // Like TextFormat::ParseFromString(). - bool ParseFromString(const std::string& input, Message* output); + bool ParseFromString(ConstStringParam input, Message* output); // Like TextFormat::Merge(). bool Merge(io::ZeroCopyInputStream* input, Message* output); // Like TextFormat::MergeFromString(). diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 0ae2def2dc..e0e4177143 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -42,7 +42,6 @@ #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include @@ -1409,9 +1409,8 @@ class TextFormatParserTest : public testing::Test { parser_.RecordErrorsTo(&error_collector); EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto)) << input << " -> " << proto->DebugString(); - EXPECT_EQ( - StrCat(line) + ":" + StrCat(col) + ": " + message + "\n", - error_collector.text_); + EXPECT_EQ(StrCat(line, ":", col, ": ", message, "\n"), + error_collector.text_); parser_.RecordErrorsTo(nullptr); } @@ -1920,18 +1919,43 @@ TEST_F(TextFormatParserTest, SetRecursionLimit) { ExpectSuccessAndTree(input, &message, nullptr); } -TEST_F(TextFormatParserTest, SetRecursionLimitUnknownField) { +TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldValue) { + const char* format = "[$0]"; + std::string input = "\"test_value\""; + for (int i = 0; i < 99; ++i) input = strings::Substitute(format, input); + std::string not_deep_input = StrCat("unknown_nested_array: ", input); + + parser_.AllowUnknownField(true); + parser_.SetRecursionLimit(100); + + unittest::NestedTestAllTypes message; + ExpectSuccessAndTree(not_deep_input, &message, nullptr); + + input = strings::Substitute(format, input); + std::string deep_input = StrCat("unknown_nested_array: ", input); + ExpectMessage( + deep_input, + "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no " + "field named \"unknown_nested_array\".\n1:123: Message is too deep, the " + "parser exceeded the configured recursion limit of 100.", + 1, 21, &message, false); + + parser_.SetRecursionLimit(101); + ExpectSuccessAndTree(deep_input, &message, nullptr); +} + +TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldMessage) { const char* format = "unknown_child: { $0 }"; std::string input; for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input); parser_.AllowUnknownField(true); + parser_.SetRecursionLimit(100); unittest::NestedTestAllTypes message; ExpectSuccessAndTree(input, &message, nullptr); input = strings::Substitute(format, input); - parser_.SetRecursionLimit(100); ExpectMessage( input, "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no " diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 1458bc000a..65c8d5469a 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -28,7 +28,6 @@ static void InitDefaultsscc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Timestamp(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Timestamp::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto = @@ -82,8 +81,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Timestamp::InitAsDefaultInstance() { -} class Timestamp::_Internal { public: }; diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 3429d7617b..e8476f6095 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -102,7 +102,6 @@ class PROTOBUF_EXPORT Timestamp PROTOBUF_FINAL : } static const Timestamp& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Timestamp* internal_default_instance() { return reinterpret_cast( &_Timestamp_default_instance_); diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto index a343d81928..3b2df6d911 100644 --- a/src/google/protobuf/timestamp.proto +++ b/src/google/protobuf/timestamp.proto @@ -91,7 +91,16 @@ option objc_class_prefix = "GPB"; // .setNanos((int) ((millis % 1000) * 1000000)).build(); // // -// Example 5: Compute Timestamp from current time in Python. +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// +// Example 6: Compute Timestamp from current time in Python. // // timestamp = Timestamp() // timestamp.GetCurrentTime() diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 8da9559110..01a79f976b 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -49,7 +49,6 @@ static void InitDefaultsscc_info_Enum_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Enum(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Enum::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Enum_google_2fprotobuf_2ftype_2eproto = @@ -66,7 +65,6 @@ static void InitDefaultsscc_info_EnumValue_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::EnumValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto = @@ -81,7 +79,6 @@ static void InitDefaultsscc_info_Field_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Field(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Field::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto = @@ -96,7 +93,6 @@ static void InitDefaultsscc_info_Option_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Option(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Option::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto = @@ -111,7 +107,6 @@ static void InitDefaultsscc_info_Type_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Type(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Type::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Type_google_2fprotobuf_2ftype_2eproto = @@ -354,10 +349,6 @@ bool Syntax_IsValid(int value) { // =================================================================== -void Type::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Type_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Type::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Type* msg); @@ -747,8 +738,6 @@ void Type::InternalSwap(Type* other) { // =================================================================== -void Field::InitAsDefaultInstance() { -} class Field::_Internal { public: }; @@ -1232,10 +1221,6 @@ void Field::InternalSwap(Field* other) { // =================================================================== -void Enum::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Enum_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Enum::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Enum* msg); @@ -1588,8 +1573,6 @@ void Enum::InternalSwap(Enum* other) { // =================================================================== -void EnumValue::InitAsDefaultInstance() { -} class EnumValue::_Internal { public: }; @@ -1856,10 +1839,6 @@ void EnumValue::InternalSwap(EnumValue* other) { // =================================================================== -void Option::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Option_default_instance_._instance.get_mutable()->value_ = const_cast< PROTOBUF_NAMESPACE_ID::Any*>( - PROTOBUF_NAMESPACE_ID::Any::internal_default_instance()); -} class Option::_Internal { public: static const PROTOBUF_NAMESPACE_ID::Any& value(const Option* msg); diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index c843794555..443aeb472a 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -215,7 +215,6 @@ class PROTOBUF_EXPORT Type PROTOBUF_FINAL : } static const Type& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Type* internal_default_instance() { return reinterpret_cast( &_Type_default_instance_); @@ -456,7 +455,6 @@ class PROTOBUF_EXPORT Field PROTOBUF_FINAL : } static const Field& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Field* internal_default_instance() { return reinterpret_cast( &_Field_default_instance_); @@ -827,7 +825,6 @@ class PROTOBUF_EXPORT Enum PROTOBUF_FINAL : } static const Enum& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Enum* internal_default_instance() { return reinterpret_cast( &_Enum_default_instance_); @@ -1042,7 +1039,6 @@ class PROTOBUF_EXPORT EnumValue PROTOBUF_FINAL : } static const EnumValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValue* internal_default_instance() { return reinterpret_cast( &_EnumValue_default_instance_); @@ -1217,7 +1213,6 @@ class PROTOBUF_EXPORT Option PROTOBUF_FINAL : } static const Option& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Option* internal_default_instance() { return reinterpret_cast( &_Option_default_instance_); @@ -1577,8 +1572,8 @@ inline bool Type::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) @@ -2209,8 +2204,8 @@ inline bool Enum::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) @@ -2497,8 +2492,8 @@ inline bool Option::has_value() const { } inline const PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const { const PROTOBUF_NAMESPACE_ID::Any* p = value_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_Any_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_Any_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::Any& Option::value() const { // @@protoc_insertion_point(field_get:google.protobuf.Option.value) diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto index 652966bb83..f501f509d1 100644 --- a/src/google/protobuf/unittest_lite.proto +++ b/src/google/protobuf/unittest_lite.proto @@ -49,6 +49,10 @@ message TestAllTypesLite { optional int64 cc = 2; } + message NestedMessage2 { + optional int32 dd = 1; + } + enum NestedEnum { FOO = 1; BAR = 2; @@ -163,6 +167,7 @@ message TestAllTypesLite { string oneof_string = 113; bytes oneof_bytes = 114; NestedMessage oneof_lazy_nested_message = 115 [lazy = true]; + NestedMessage2 oneof_nested_message2 = 117; } // Tests toString for non-repeated fields with a list suffix diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h index 7b5ce52b82..9058bbef15 100644 --- a/src/google/protobuf/util/field_comparator.h +++ b/src/google/protobuf/util/field_comparator.h @@ -170,6 +170,7 @@ class PROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator { // Defines the map to store the tolerances for floating point comparison. typedef std::map ToleranceMap; + friend class MessageDifferencer; // The following methods get executed when CompareFields is called for the // basic types (instead of submessages). They return true on success. One // can use ResultFromBoolean() to convert that boolean to a ComparisonResult diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index 9ed35e643b..f639b32678 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -33,12 +33,12 @@ #include #include -#include -#include #include #include #include #include +#include +#include namespace google { namespace protobuf { diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 71e2d2ea8f..1a9cc9bf41 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -810,8 +810,8 @@ Status ProtoStreamObjectSource::RenderNonMessageField( const google::protobuf::Field* field, StringPiece field_name, ObjectWriter* ow) const { // Temporary buffers of different types. - uint32 buffer32; - uint64 buffer64; + uint32 buffer32 = 0; + uint64 buffer64 = 0; std::string strbuffer; switch (field->kind()) { case google::protobuf::Field::TYPE_BOOL: { diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 70861634d7..817109b02d 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -588,6 +588,38 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( if (field == nullptr) return this; + // Legacy JSON map is a list of key value pairs. Starts a map entry object. + if (options_.use_legacy_json_map_format && name.empty()) { + Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); + return this; + } + + if (IsMap(*field)) { + // Begin a map. A map is triggered by a StartObject() call if the current + // field has a map type. + // A map type is always repeated, hence set is_list to true. + // Render + // "": [ + Push(name, Item::MAP, false, true); + return this; + } + + if (options_.disable_implicit_message_list) { + // If the incoming object is repeated, the top-level object on stack should + // be list. Report an error otherwise. + if (IsRepeated(*field) && !current_->is_list()) { + IncrementInvalidDepth(); + + if (!options_.suppress_implicit_message_list_error) { + InvalidValue( + field->name(), + "Starting an object in a repeated field but the parent object " + "is not a list"); + } + return this; + } + } + if (IsStruct(*field)) { // Start a struct object. // Render @@ -611,22 +643,6 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( return this; } - // Legacy JSON map is a list of key value pairs. Starts a map entry object. - if (options_.use_legacy_json_map_format && name.empty()) { - Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); - return this; - } - - if (IsMap(*field)) { - // Begin a map. A map is triggered by a StartObject() call if the current - // field has a map type. - // A map type is always repeated, hence set is_list to true. - // Render - // "": [ - Push(name, Item::MAP, false, true); - return this; - } - // A regular message type. Pass it directly to ProtoWriter. // Render // "": { diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index f3aeb61f11..cc68c6b1b4 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -100,6 +100,13 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // If true, accepts repeated key/value pair for a map proto field. bool use_legacy_json_map_format; + // If true, disable implicitly creating message list. + bool disable_implicit_message_list; + + // If true, suppress the error of implicitly creating message list when it + // is disabled. + bool suppress_implicit_message_list_error; + Options() : struct_integers_as_strings(false), ignore_unknown_fields(false), @@ -107,7 +114,9 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { use_lower_camel_for_enums(false), case_insensitive_enum_parsing(false), ignore_null_value_map_entry(false), - use_legacy_json_map_format(false) {} + use_legacy_json_map_format(false), + disable_implicit_message_list(false), + suppress_implicit_message_list_error(false) {} // Default instance of Options with all options set to defaults. static const Options& Defaults() { diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index f5e0860c1c..829a18aae6 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -916,6 +917,76 @@ bool MessageDifferencer::IsMatch( return match; } +bool MessageDifferencer::CompareMapFieldByMapReflection( + const Message& message1, const Message& message2, + const FieldDescriptor* map_field) { + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + const int count1 = reflection1->MapSize(message1, map_field); + const int count2 = reflection2->MapSize(message2, map_field); + const bool treated_as_subset = IsTreatedAsSubset(map_field); + if (count1 != count2 && !treated_as_subset) { + return false; + } + if (count1 > count2) { + return false; + } + const FieldDescriptor* val_des = map_field->message_type()->map_value(); + switch (val_des->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + for (MapIterator it = reflection1->MapBegin( \ + const_cast(&message1), map_field); \ + it != \ + reflection1->MapEnd(const_cast(&message1), map_field); \ + ++it) { \ + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { \ + return false; \ + } \ + MapValueRef value2; \ + reflection2->InsertOrLookupMapValue(const_cast(&message2), \ + map_field, it.GetKey(), &value2); \ + if (!default_field_comparator_.Compare##COMPAREMETHOD( \ + *val_des, it.GetValueRef().Get##METHOD(), \ + value2.Get##METHOD())) { \ + return false; \ + } \ + } \ + break; \ + } + HANDLE_TYPE(INT32, Int32Value, Int32); + HANDLE_TYPE(INT64, Int64Value, Int64); + HANDLE_TYPE(UINT32, UInt32Value, UInt32); + HANDLE_TYPE(UINT64, UInt64Value, UInt64); + HANDLE_TYPE(DOUBLE, DoubleValue, Double); + HANDLE_TYPE(FLOAT, FloatValue, Float); + HANDLE_TYPE(BOOL, BoolValue, Bool); + HANDLE_TYPE(STRING, StringValue, String); + HANDLE_TYPE(ENUM, EnumValue, Int32); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + for (MapIterator it = reflection1->MapBegin( + const_cast(&message1), map_field); + it != + reflection1->MapEnd(const_cast(&message1), map_field); + ++it) { + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { + return false; + } + MapValueRef value2; + reflection2->InsertOrLookupMapValue(const_cast(&message2), + map_field, it.GetKey(), &value2); + if (!Compare(it.GetValueRef().GetMessageValue(), + value2.GetMessageValue())) { + return false; + } + } + break; + } + } + return true; +} + bool MessageDifferencer::CompareRepeatedField( const Message& message1, const Message& message2, const FieldDescriptor* repeated_field, @@ -923,6 +994,25 @@ bool MessageDifferencer::CompareRepeatedField( // the input FieldDescriptor is guaranteed to be repeated field. const Reflection* reflection1 = message1.GetReflection(); const Reflection* reflection2 = message2.GetReflection(); + + // When both map fields are on map, do not sync to repeated field. + // TODO(jieluo): Add support for reporter + if (repeated_field->is_map() && reporter_ == nullptr && + field_comparator_ == nullptr) { + const FieldDescriptor* key_des = repeated_field->message_type()->map_key(); + const FieldDescriptor* val_des = + repeated_field->message_type()->map_value(); + const internal::MapFieldBase* map_field1 = + reflection1->GetMapData(message1, repeated_field); + const internal::MapFieldBase* map_field2 = + reflection2->GetMapData(message2, repeated_field); + if (map_field1->IsMapValid() && map_field2->IsMapValid() && + ignored_fields_.find(key_des) == ignored_fields_.end() && + ignored_fields_.find(val_des) == ignored_fields_.end()) { + return CompareMapFieldByMapReflection(message1, message2, repeated_field); + } + } + const int count1 = reflection1->FieldSize(message1, repeated_field); const int count2 = reflection2->FieldSize(message2, repeated_field); const bool treated_as_subset = IsTreatedAsSubset(repeated_field); diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index f7317c80fe..35a04afbcb 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -177,43 +177,33 @@ class PROTOBUF_EXPORT MessageDifferencer { // For known fields, "field" is filled in and "unknown_field_number" is -1. // For unknown fields, "field" is NULL, "unknown_field_number" is the field // number, and "unknown_field_type" is its type. - const FieldDescriptor* field; - int unknown_field_number; - UnknownField::Type unknown_field_type; + const FieldDescriptor* field = nullptr; + int unknown_field_number = -1; + UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT; // If this a repeated field, "index" is the index within it. For unknown // fields, this is the index of the field among all unknown fields of the // same field number and type. - int index; + int index = -1; // If "field" is a repeated field which is being treated as a map or // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates // the index the position to which the element has moved. If the element // has not moved, "new_index" will have the same value as "index". - int new_index; + int new_index = -1; // For unknown fields, these are the pointers to the UnknownFieldSet // containing the unknown fields. In certain cases (e.g. proto1's // MessageSet, or nested groups of unknown fields), these may differ from // the messages' internal UnknownFieldSets. - const UnknownFieldSet* unknown_field_set1; - const UnknownFieldSet* unknown_field_set2; + const UnknownFieldSet* unknown_field_set1 = nullptr; + const UnknownFieldSet* unknown_field_set2 = nullptr; // For unknown fields, these are the index of the field within the // UnknownFieldSets. One or the other will be -1 when // reporting an addition or deletion. - int unknown_field_index1; - int unknown_field_index2; - - SpecificField() - : field(NULL), - unknown_field_number(-1), - index(-1), - new_index(-1), - unknown_field_set1(NULL), - unknown_field_set2(NULL), - unknown_field_index1(-1), - unknown_field_index2(-1) {} + int unknown_field_index1 = -1; + int unknown_field_index2 = -1; }; // Abstract base class from which all MessageDifferencer @@ -767,6 +757,11 @@ class PROTOBUF_EXPORT MessageDifferencer { const FieldDescriptor* field, std::vector* parent_fields); + // Compare the map fields using map reflection instead of sync to repeated. + bool CompareMapFieldByMapReflection(const Message& message1, + const Message& message2, + const FieldDescriptor* field); + // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. bool CompareFieldValue(const Message& message1, const Message& message2, const FieldDescriptor* field, int index1, int index2); diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index 2f6be98ccd..3d36e8593c 100644 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -160,6 +160,29 @@ TEST(MessageDifferencerTest, MapFieldEqualityTest) { // Compare EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Get map entries by index will sync map to repeated field + MapTestUtil::GetMapEntries(msg1, 0); + EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare values not match + (*msg1.mutable_map_int32_int32())[1] = 2; + (*msg2.mutable_map_int32_int32())[1] = 3; + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare keys not match + msg1.Clear(); + msg2.Clear(); + (*msg1.mutable_map_string_string())["1"] = ""; + (*msg2.mutable_map_string_string())["2"] = ""; + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare message values not match + msg1.Clear(); + msg2.Clear(); + (*msg1.mutable_map_int32_foreign_message())[1].set_c(1); + (*msg2.mutable_map_int32_foreign_message())[1].set_c(2); + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); } TEST(MessageDifferencerTest, BasicPartialEqualityTest) { diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index fc9e6a5e6f..e3463e3512 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -36,7 +36,6 @@ #include #include -#include #include #include #include @@ -49,6 +48,7 @@ #include #include #include +#include #include #include #include diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index e9f53a53d1..21debfcb80 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -60,7 +60,6 @@ static void InitDefaultsscc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto( new (ptr) PROTOBUF_NAMESPACE_ID::BoolValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::BoolValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto = @@ -74,7 +73,6 @@ static void InitDefaultsscc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::BytesValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::BytesValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto = @@ -88,7 +86,6 @@ static void InitDefaultsscc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::DoubleValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DoubleValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto = @@ -102,7 +99,6 @@ static void InitDefaultsscc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::FloatValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FloatValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto = @@ -116,7 +112,6 @@ static void InitDefaultsscc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Int32Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Int32Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto = @@ -130,7 +125,6 @@ static void InitDefaultsscc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Int64Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Int64Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto = @@ -144,7 +138,6 @@ static void InitDefaultsscc_info_StringValue_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::StringValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::StringValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto = @@ -158,7 +151,6 @@ static void InitDefaultsscc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::UInt32Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UInt32Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto = @@ -172,7 +164,6 @@ static void InitDefaultsscc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::UInt64Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UInt64Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto = @@ -303,8 +294,6 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -void DoubleValue::InitAsDefaultInstance() { -} class DoubleValue::_Internal { public: }; @@ -498,8 +487,6 @@ void DoubleValue::InternalSwap(DoubleValue* other) { // =================================================================== -void FloatValue::InitAsDefaultInstance() { -} class FloatValue::_Internal { public: }; @@ -693,8 +680,6 @@ void FloatValue::InternalSwap(FloatValue* other) { // =================================================================== -void Int64Value::InitAsDefaultInstance() { -} class Int64Value::_Internal { public: }; @@ -890,8 +875,6 @@ void Int64Value::InternalSwap(Int64Value* other) { // =================================================================== -void UInt64Value::InitAsDefaultInstance() { -} class UInt64Value::_Internal { public: }; @@ -1087,8 +1070,6 @@ void UInt64Value::InternalSwap(UInt64Value* other) { // =================================================================== -void Int32Value::InitAsDefaultInstance() { -} class Int32Value::_Internal { public: }; @@ -1284,8 +1265,6 @@ void Int32Value::InternalSwap(Int32Value* other) { // =================================================================== -void UInt32Value::InitAsDefaultInstance() { -} class UInt32Value::_Internal { public: }; @@ -1481,8 +1460,6 @@ void UInt32Value::InternalSwap(UInt32Value* other) { // =================================================================== -void BoolValue::InitAsDefaultInstance() { -} class BoolValue::_Internal { public: }; @@ -1676,8 +1653,6 @@ void BoolValue::InternalSwap(BoolValue* other) { // =================================================================== -void StringValue::InitAsDefaultInstance() { -} class StringValue::_Internal { public: }; @@ -1885,8 +1860,6 @@ void StringValue::InternalSwap(StringValue* other) { // =================================================================== -void BytesValue::InitAsDefaultInstance() { -} class BytesValue::_Internal { public: }; diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index c55e9a348f..455a50f4e9 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -134,7 +134,6 @@ class PROTOBUF_EXPORT DoubleValue PROTOBUF_FINAL : } static const DoubleValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DoubleValue* internal_default_instance() { return reinterpret_cast( &_DoubleValue_default_instance_); @@ -271,7 +270,6 @@ class PROTOBUF_EXPORT FloatValue PROTOBUF_FINAL : } static const FloatValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FloatValue* internal_default_instance() { return reinterpret_cast( &_FloatValue_default_instance_); @@ -408,7 +406,6 @@ class PROTOBUF_EXPORT Int64Value PROTOBUF_FINAL : } static const Int64Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Int64Value* internal_default_instance() { return reinterpret_cast( &_Int64Value_default_instance_); @@ -545,7 +542,6 @@ class PROTOBUF_EXPORT UInt64Value PROTOBUF_FINAL : } static const UInt64Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UInt64Value* internal_default_instance() { return reinterpret_cast( &_UInt64Value_default_instance_); @@ -682,7 +678,6 @@ class PROTOBUF_EXPORT Int32Value PROTOBUF_FINAL : } static const Int32Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Int32Value* internal_default_instance() { return reinterpret_cast( &_Int32Value_default_instance_); @@ -819,7 +814,6 @@ class PROTOBUF_EXPORT UInt32Value PROTOBUF_FINAL : } static const UInt32Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UInt32Value* internal_default_instance() { return reinterpret_cast( &_UInt32Value_default_instance_); @@ -956,7 +950,6 @@ class PROTOBUF_EXPORT BoolValue PROTOBUF_FINAL : } static const BoolValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const BoolValue* internal_default_instance() { return reinterpret_cast( &_BoolValue_default_instance_); @@ -1093,7 +1086,6 @@ class PROTOBUF_EXPORT StringValue PROTOBUF_FINAL : } static const StringValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const StringValue* internal_default_instance() { return reinterpret_cast( &_StringValue_default_instance_); @@ -1237,7 +1229,6 @@ class PROTOBUF_EXPORT BytesValue PROTOBUF_FINAL : } static const BytesValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const BytesValue* internal_default_instance() { return reinterpret_cast( &_BytesValue_default_instance_); diff --git a/tests.sh b/tests.sh index 52b9cf127b..3d47b6cbf2 100755 --- a/tests.sh +++ b/tests.sh @@ -314,7 +314,7 @@ build_python() { if [ $(uname -s) == "Linux" ]; then envlist=py\{27,33,34,35,36\}-python else - envlist=py27-python + envlist=py\{27,36\}-python fi tox -e $envlist cd .. @@ -364,7 +364,7 @@ build_python_cpp() { if [ $(uname -s) == "Linux" ]; then envlist=py\{27,33,34,35,36\}-cpp else - envlist=py27-cpp + envlist=py\{27,36\}-cpp fi tox -e $envlist cd .. @@ -701,6 +701,51 @@ build_php7.4_zts_c() { popd } +build_php8.0() { + use_php 8.0 + pushd php + rm -rf vendor + composer update + composer test + popd + (cd conformance && make test_php) +} + +build_php8.0_c() { + IS_64BIT=$1 + use_php 8.0 + php/tests/test.sh + pushd conformance + if [ "$IS_64BIT" = "true" ] + then + make test_php_c + else + make test_php_c_32 + fi + popd +} + +build_php8.0_c_64() { + build_php8.0_c true +} + +build_php8.0_mixed() { + use_php 8.0 + pushd php + rm -rf vendor + composer update + tests/compile_extension.sh + tests/generate_protos.sh + php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit + popd +} + +build_php8.0_all() { + build_php8.0 + build_php8.0_c_64 + build_php8.0_mixed +} + build_php_all_32() { build_php5.5 build_php5.6